88
Wrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy of X”) David L. R. Houston University of Vermont

Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

  • Upload
    vulien

  • View
    213

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Wrestling with AlligatorsPutting OS X in anOpen Access Lab

(or “The Joy of X”)

David L. R. HoustonUniversity of Vermont

SIGUCCS XXVISan Antonio, Texas

Page 2: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

September 21st, 2003

Wrestling with Alligators: putting OS X in an open access lab (or “The Joy of X”)Mac OS X has been around for a few years, but many lab managers are still struggling to wrestle it into a lab environment. Many are new to OS X, may be new to Macintosh and may be even newer to UNIX. Learning how to configure, image and deploy this new breed of Mac OS is a daunting challenge, and often a process of experimentation. It doesn’t have to be difficult.

This paper builds on over 2 years of R&D, and will guide participants through the entire process. Included are issues about security, authentication using LDAP, configuring a master machine, creating an image of that machine, and finally, cloning that master image to a different machine. Strategies for deployment will be discussed, and many of the OS-specific areas that require careful attention and special treatment will be covered in depth.

What is OS X?OS X is Apple Computer’s latest operating system. Introduced in 2000 as a “public beta”, it is a major departure from the more traditional Macintosh operating system, despite the fact that the roots of the system almost predate the original Macintosh operating system. The changes bring a fresh and vital system to computing.

As a candidate for use in an open access computing lab in a college or university setting, OS X offers a lot of promise. With this promise comes a raft of challenges, all of which require care and feeding. It may seem daunting at this stage – you are, after all, mapping out a plan to deploy a lot of UNIX workstations. It is, however, very doable. You too can wrestle with alligators and know the true “Joy of X”.

UNIXFundamentally, OS X is a UNIX system. For those of you well versed in System 9 and earlier, this will be the most significant change. You might notice the most radical change in the idea of a command line interface, something that was entirely absent in all previous versions of the Macintosh OS.

The real roots of the UNIX “flavor” for OS X originate in the NEXTStep system. You may recall that NEXT was the company founded by Steve Jobs after he left Apple the first time around. Much of NEXTStep originated in Smalltalk, a product of Xerox PARC research. NEXT too was a UNIX system, but geared toward the programmer, not the end-user.

The subsequent steps to OS X are something that might be rhapsodized someday from the Apple archives. The marriage of Mac and NEXT did not pave the road to OS X directly. That step was mediated by the incorporation of a larger community of UNIX development, specifically in the

Wrestling Alligators SIGUCCS 2003 Page 2

Page 3: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

form of FreeBSD, one of a number of Open Source UNIX flavors. All of these come from the very early development efforts of both System V (from Bell Labs) and Berkeley Labs.

Originally called MULTICS (Multiplexed Information Computing System), UNIX originated as a joint venture between General Electric and AT&T Bell Labs. Primarily a research system, it underwent a number of developments before finally emerging as the UNIX we know and use today. Running on the creaky DEC PDP series of computers, it took almost another decade until it was available for text processing. It was at this stage that the system became more than an esoteric tool and instead began to see widespread use, fostering projects like the C language and networking. UNIX put down roots in many places, including the University of California at Berkeley.

What matters in terms of OS X is not a detailed history – we’d be here a long time for that – but that OS X has a long historical root that also makes it part of a larger project, Open Source. This matters because it presents us with both a virtue and a vice: we have a huge library of well-tested software available for use, but we also have to recognize the accompanying security issues as they arise.

Major departure from pre- X operating system (OS9)We noted earlier the major difference found in OS X: the command line interface. This is probably a key distinguishing characteristic of OS X when contrasted with earlier Macintosh operating systems. The command line interface or CLI might seem daunting. If you cut your teeth on OS9 or earlier, using a CLI is going to take some getting used to. Don’t be dismayed. It is a lot easier than you might think.

Graphically there are differences as well. The “aqua” design theme is very different from OS9. Gone are the familiar (and sometimes annoying) vestiges that were standard “Mac”: Chooser, Extensions, etc. The graphical part of OS X, though, can fool you. In many cases, the graphics are really just a way to manage a command line series of actions – you can, in many cases, do the same thing with a lot of typing and reading of man pages. For example, we can manipulate the entire NetInfo database through either the NetInfo utility (found in /Applications/Utilities/) or use the series of commands: nidump, niload, etc. We’ll look at this particular set of utilities later on.

The best way to dive in to the CLI is to start the Terminal program (/Applications/Utilities). Try typing man man at the command prompt. This is built-in help system for all UNIX-based systems. Typing man and some other command will give you a (usually) verbose page of instructions, flags, and even other references to check.

Not sure what to type in to do a particular task? Simple enough: try this example by typing man –k netinfo and see what you get (you can also type apropos netinfo and get the same results). This illustrates the use of keywords to try to discover more about UNIX commands (man –k is the man command with the optional flag –k which stands for keyword). Try this one: man –k ‘directory listing’ (the use of single quotes means we get results with that phrase and not the two words separately). You’ll get a series of lines that mention the command to use and a brief description of each command. This illustrates how you can type in “plain English” and see what pops up. It might seem a bit confusing, because some of the lines you get back are actually

Wrestling Alligators SIGUCCS 2003 Page 3

Page 4: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

system calls and are used by programmers writing C routines. Many of the commands, though, are very useful, and are usually identifiable by virtue of their being in lower case. Look at the ls(1) line. It says “list directory contents”. Try typing it as a command. Typing ls gives you a listing of the contents of the current directory (synonymous with folder in the older Mac OS).

There is a lot out there for command line UNIX. You have to poke around a bit, and you have to know when not to do something (when you are logged in as root you can really break things – we will look at this later). But you can learn a lot quickly and get a lot done in ways you might not know much about if you come from a traditional Macintosh environment. This is the power of OS X.

Long heritageThe same lengthy heritage that seems to make the new Mac OS X a bit daunting can also be a real asset. The same foundation of FreeBSD also serves as a repository of knowledge: man pages, discussion forums, open source software are all available to you as you navigate OS X.

The learning curveYou will face a learning curve here – make no mistake about it. Depending upon your experience and abilities, you should try to make time to explore OS X. The best way is, of course, by everyday use. Certainly, spending time working with the UNIX command line stuff and all of the commands is an essential part of this process. In the appendix, I’ve listed a number of useful references you may want to check out.

Getting used to the GUI part of things will probably take a lot less time, but it is still a needed part of the process. You’ll discover that the “new” Macintosh graphical interface has some familiarity and some surprises.

The ToolkitAs with all things computing, we need a toolkit that makes the job not just easier, but in this case, doable! This section inventories the tools you will need to get the job done.

One machine as masterI am a strong proponent of having the machine you are working on available as part of the toolkit. Having said that, though, I am all too aware of the reality of budgets and the simple fact that for many, this is not an option. Clearly, not having a machine to work on, to “break”, to experiment with is going to limit your options. If you face a restriction here, I would probably suggest you seriously look at setting up an older machine first, to really twiddle and break. Expect to have to rebuild and reinstall more than a few times. You might be surprised at how well OS X performs on older hardware, and this gives you a chance to get your feet wet.

If you are able to get a machine that is “first cut,” it (ideally) will be the same hardware you are going to deploy. This is the ideal to shoot for. One interesting aside: many have reported that the use of an OS X image for a new model Macintosh can be used to clone older Macintosh hardware. Do not try to go the other way, though!

Wrestling Alligators SIGUCCS 2003 Page 4

Page 5: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

One machine as cloneNoting the same restrictions mentioned in the previous section, if you can get a second, identical piece of hardware to operate with, you are much better off. This second machine is the one you will really “burn” several times. It’s where all your practice cloning takes place. In addition, you will quickly discover that, having now cloned the master, this second machine is a really good place to do any cutting edge experimentation on. If it works, take your changes over to the master. If it crashes and burns beyond all recognition, re-clone it, and you are back in business.

Of course, this same lesson can be applied to the master, and so this important axiom has been a cornerstone of my work on all platforms: build your master image in layers, beginning with the most basic and best understood. As you progress, make an image of that particular layer, discarding the previous ones. If you do it this way, a serious mistake is unlikely to cost you more than a few hours at worst. If you don’t do it this way, that same boo-boo might very well set you back weeks as you attempt to recreate the base master image entirely from scratch! It’s your choice, but I’d sure advise the first approach.

Carbon Copy ClonerCarbon Copy Cloner is the brainchild of Mike Bombich (www.bombich.com). It is actually an AppleScript Studio “interface” to existing command line tools (surprise!): asr (Apple Software Restore) and ditto. You might want to do a man page on both asr and ditto – they provide very interesting reading!

Carbon Copy Cloner or CCC offers a means of backing up an OS X disk. It does this by effectively taking a complete “snapshot” of the hard drive to back up and creating an image file (suffix .img). NetRestore or Apple’s Disk copy program can work with these image files (we’ll be working with NetRestore later on).

In addition to making backups, CCC is also the tool of choice for the production of your master image file. It takes a complex set of command line options that we would have to use in the asr tool and puts a nice human interface on it all. Perhaps more significantly for our purposes, it forces the resulting image file to be fully asr “ready” for use by NetRestore and later cloning.

A few caveats to note here (and we’ll remember these later on): CCC can make some big images. Turning on the compression really helps, but unlike something like Symantec Ghost (used for Windows to do something similar), we don’t have any compression options – you get what you get! Also note that creation of a large image file takes quite a long time, so be prepared to “hurry up and wait”.

NetRestoreNetRestore is also brought to you by Mike Bombich (www.bombich.com). NetRestore is a marvelous little utility designed to allow the restoration of a complete hard drive image. The source image can be on a local partition, on a FireWire drive, on a CD (if it fits, of course!) or on the network somewhere.

Wrestling Alligators SIGUCCS 2003 Page 5

Page 6: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Use is very simple and can be really quick. A FireWire drive used as the boot device with a 2 gigabyte image file on that same FireWire drive can restore to the local hard disk in under 10 minutes.

In addition, it is possible to do some critical post-processing using shell scripts, Perl scripts or AppleScript scripts to do all sort of things. In this paper, I talk about the use of these post-processing scripts to fix something called ByHost references found in the innards of OS X.

A few caveats: I have found that if one has a faulty master image, then NetRestore is likely to erroneously report the cloning/restoration as being complete when it is not. This is not a huge problem, because you can always do it again. You will know this has happened when the restore time is reported as something like .08799999 seconds!

Both CCC and NetRestore are free for educational users. All others must pay cash! If you are in education, you cannot go wrong with these tools.

FireWire driveThe changes in storage recently are nothing short of astonishing, and adding a FireWire drive to your stable of goodies is a really good idea. It is faster, very versatile and gives you a lot of flexibility in how you do this job. Of course, not all hardware you work with has the FireWire port, so you may need the older SCSI. Without any external drive options at all, you are likely to face an uphill battle here.

Your toolkit is one of the most important things you can develop as you wrestle with the OS X Alligator.

SecuritySecurity is almost the centerpiece of how the process of imaging and cloning takes place. There is a lot here that is very new and very different for experienced Mac OS9 users and administrators, and it’s also one of the most important parts of the entire process. Don’t be put off – it is all very doable, but you do have to work your way through it carefully.

Different from the pastBefore OS X, the Macintosh was a low security risk. For starters, the overall audience was smaller and that made for an inherently lower risk window. In addition, the absence of any sort of command line, coupled with the lack of particular types of network tools and devices made a Mac Hack uncommon. All that has changed.

UNIX has long been a domain for experimentation, and this includes certain types of activities that are, shall we say, “undesirable”. I’ll refrain from simply branding it all “hacking” because that term has other connotations that are not bad at all. Suffice to say that the newly minted OS X presents itself as much more than a Macintosh – it is a full featured flavor of UNIX and, in addition to the all of the goodies such as Open Source software, we also inherit all the baddies such as crack and other choice nuggets. Security on a serious level has not only arrived for the Macintosh, it is now essential.

Wrestling Alligators SIGUCCS 2003 Page 6

Page 7: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

You may discover that others scoff at the issues raised here or pay little attention to the possibilities. I’ll confess: I’ve probably hung around a lot of system administrators whose idea of a secure installation is a tiny concrete bunker with no keys to the locks and no power! To those who suggest that security is a non-issue for OS X, I would reply this way: it will only take one episode of serious abuse to create the potential for major problems. A really clever person – and there are many more out there who are much cleverer than I – could, if they gained root access, quickly enable an OS X box for all sorts of things, many of which might take months to discover and turn off, long after any damage is done.

Why it mattersWhat sorts of things might we see? It is easy to set up an Apache web server, the most commonly used web server in the world today. I can think of a few things I would rather not have to deal with on an unmanaged web server. It is easy to configure ssh and allow anyone in. It is easy to set up packet “sniffers” that discretely examine every single incoming and outgoing packet, conveniently mailing the results to some distant email account. All of this and more is relatively simple to do, and many of the instructions for doing these things are found on the Wild, Wild Web! And lest we forget too quickly: setting up remote machines to launch a Denial of Service attack is also quite feasible with the right tools. Are these things you want to leave open to chance?

If it seems scary, it is. It is also quite manageable. You have to take certain steps to preclude these events from happening, and from that point on, you are reasonably secure (there’s no such thing as 100% secure, but you can come pretty close).

Open FirmwareIntroduced in recent models, Open firmware is actually not new with OS X. OS9 machines also had this feature, and it provides some useful features. With OS X, though, it provides some big security holes, ones that you must take care to protect.

Open firmware is a way for a machine to access certain kinds of parameters at boot time. These settings are stored in non-volatile RAM space. It is similar to the older parameter ram. The primary difference is that the Open firmware model is a platform independent one. In fact, it was originally developed by Sun Microsystems.

What can you do with Open Firmware? Plenty! For starters, the default configuration for Open firmware allows any user to boot from a CD. This means that any user can boot from an OS X installation CD and set or reset the root password! You don’t want this. It is easy to protect against this condition using the setenv and security-mode commands. In conjunction with the password command, one can prevent booting from a CD with a few simple steps (shown later).

Note that the entire Open firmware interface is a command-line affair. It is possible to set, examine and reset open firmware settings using the Terminal utility and even a few GUI applications. I would strongly suggest, though, that you become acquainted with the CLI simply because if you have a serious problem with the system, you might not be able to get in to the GUI system. Understanding and using the native CLI for Open Firmware is a real help.

Wrestling Alligators SIGUCCS 2003 Page 7

Page 8: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

In addition to setting security modes and passwords, Open firmware allows you to set the boot-device. You can also read files on the main disk, establish limited networking services and change disk information. It’s unlikely you’d want to do any of the last three things I’ve mentioned, but it does go to show that having an unsecured Open Firmware leaves the machine very vulnerable to outside influence.

Access to Open Firmware is very simple. At power on, simply hold down the OPTION O F keys. The command line interface will appear.

One final note: once you have entered a password, do not forget it! It is possible to manipulate the hardware – remove a DIMM, power on, power off, replace a DIMM – and reset the password to an empty value, but this can be a major pain. Other than this, there is no way to reset or recover a forgotten password!

Single User modeSingle user mode is a UNIX feature designed to allow a system administrator access to an ailing machine. When a UNIX box boots into single-user mode, it is generally very limited in what kinds of services it can offer, and it is not enabled for multiple users. In fact, the superuser or root is the only user that can work in this mode.

For the OS X system, this same rule applies, and herein lies the problem. Once booted into single user mode, the root account is automatically logged in and does not require a password. After this, it is a simple process to check the disk and mount the entire file system as read-write. Why does this matter? Simple enough: once root has a read-write file system, it is easy to setup that Apache web server, configure ssh, even mail the password file for later cracking.

There is not a lot you can do to protect yourself once the user has booted to single user mode. But you can prevent it from happening at all by enabling command security and setting a password in Open firmware. Once again, this is a compelling reason to work with Open firmware: it is the first and probably best line of defense.

RootYou have noticed the term superuser and root in the preceding discussions. These may be new to Macintosh users experienced in previous OS versions. The root user, or superuser (these are the same thing) is a special UNIX account. This particular user can do anything – absolutely anything – to a system. As a result, you must use great care. An inadvertent rm could easily render your wonderful master image into an attractive bookend!

By default, OS X ships with the root account disabled. This means that should you encounter a situation that requires root access (and there not a lot of these, but they do crop up), you might have to enable it. There is a good alternative, which we’ll talk about in a moment.

In my earlier efforts with Mac OS X, I advocated enabling the root account and setting it up with a good, strong password. Since then, I have changed my tack quite a bit. Simply put: I now leave the root account disabled and use a combination of methods which includes sudo to not

Wrestling Alligators SIGUCCS 2003 Page 8

Page 9: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

only make full root and administrative access possible, but also allows one to have no local accounts at all on a finished machine, making that part of security very strong.

The sudo facility is a very powerful tool. Sudo allows one to act as root (sudo translates to Superuser do), doing anything root can do. In addition, it is very configurable, meaning that you can, if you like, set things up to allow only certain programs to be used by certain users. By default, any local account on the OS X machine that is an administrative account can use sudo and have complete machine access. One useful tip: if you have a lot of things to do as root, and are logged in as an administrator, you can simply type sudo sh and “become” root for as long as you are in the invoked shell. You can also use tcsh this way as well.

One last note: having the root account disabled does not mean that booting into single-user mode will not work: it very much will work. Consequently, you must still secure Open Firmware to protect against intrusion via the single-user mode boot. A disabled root account is only meaningful in the context of a regular boot and the use of the Aqua interface, including the Terminal application.

Local accountsAs part of the larger security audit, I have moved away from having any local accounts at all. Local accounts are any accounts used to log in to the machine without any type of network-based authentication. These are the accounts you create when you first setup a new OS X installation. For a new installation, note that the default account type for the first user you create is that of an administrative user. Since administrative users are automatically allowed to use the sudo facility, you need to be sure that you manage this carefully.

Your users cannot be administratorsIt may seem obvious at this point, but you also must be certain that your regular users are not administrative users, since the administrative class of user has access to things that make root use possible. Unless there is an overwhelming need to do so, never make it possible for a regular user to be an administrator.

If you use a network based authentication method (we’ll be discussing the use of LDAP later on), then you are all set, since no user that logs in via most properly configured methods will be anything except a non-administrative user.

Why does this whole administrative user thing even matter? If you have worked with OS X at all, you have certainly discovered that one of the most common things required in the installation of almost any piece of software, including system updates, is the entry of an administrative username and password. This is a new convention with OS X, something not found in the earlier Macintosh operating system. If you make administrative access readily available, you may have more on your hands than you bargained for! Additionally, administrative users can configure the infrastructure of the machine – remote access, sharing, enabling root user, etc. making this a real problem.

Wrestling Alligators SIGUCCS 2003 Page 9

Page 10: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Why Classic mode should go awayClassic mode is the add-on to OS X that makes it possible to run older “legacy” applications under OS X. If you start Classic mode or an application that requires it, the familiar “Welcome to Macintosh” appears in a separate window and the equivalent of OS9 starts.

There are, as of this writing, a number of “must-have” applications that are not OS X native and so require Classic mode to run. If you are in the position of having to offer such applications, then you are going to have some extra work. Since I have decided not to offer Classic at all, I can’t cover the issues in getting secure. There is an excellent resource to be found on the Bombich software site that offers a script to secure Classic, however.

Even with a secured Classic, there are some potentially serious security issues at stake. To mention a few: with OS9 installed, it is possible under some configurations to boot into OS9 and then destroy or severely compromise the entire OS X installation. Having Classic mode available does make it possible to run applications like FWSucker, granting the user your Open Firmware password. With Classic installed and not properly secured, any user could find the password file for OS X and, if you still have local accounts, merrily start a crack run on it. In short, Classic poses a measurable security risk and should only be used if it essential.

The last reason to avoid Classic is more pragmatic – it adds a layer of complexity and instability for the user. Configuring printing and network access is certainly doable, but from the user perspective, can get dicey when working in both OS X and OS9 and having to move things around over the network.

So again, my last word is simple: don’t use classic mode if you can possibly avoid it!

ConfigurationNow we begin to look at the nitty-gritty details involved in configuration. This section is broken down into specific categories, and begins with the essential element of security.

Open FirmwareAs noted earlier, the very first step is to secure Open Firmware. Do this by booting the machine and holding down the OPTION O F keys. The command line interface appears:

Apple PowerMac3, 5 4.2.3f1 BootROM built on 08/01/01 at 11:14:42Copyright 1994-2001 Apple Computer, Incorporated.All Rights Reserved

Welcome to open firmware. The system time and date is 15:03:42 12/3/02

To continue booting, type “mac-boot” and press return.To shut down, type “shutdown” and press return.

Release keys to continue!

Ok0>

Wrestling Alligators SIGUCCS 2003 Page 10

Page 11: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Now, set the password:

0 >passwordEnter a new password: ******Enter password again: ******Password will be in place after next boot! ok

The commands you type are shown in bold – press enter after typing in a command. The system response is usually the terse ‘ok’.

Find a way to remember this password!

Finally, set the security mode level:

0 >setenv security-mode command ok

Then reboot the machine:

0 >reset-all ok

Open Firmware is now secure.

AuthenticationThere are several methods available to facilitate authentication. By default, OS X uses locally based methods – that is, the user attempting to login must have an account on the local machine in order to use it. For open access lab purposes, this is not usually practical or desirable, so we turn to network based schemes to do this,

Local or network?Earlier, we discussed some of the ramifications of local versus remote accounts. With local accounts, we are always open to the possibility that a malicious user gains access to the password file and cracks the passwords. If all local accounts are disabled, however, this is a moot point.

With all local accounts disabled, though, we face an entirely different problem. How do we log in as an administrator in order to install software? There are several aspects to this question.

First, software installations fall into two general categories: applications and system. For system upgrades – the kind you see when the Software Update application runs – you can, with the system properly configured, perform this as a remotely logged in user as long as you have the ability to use the sudo facility. Try the man command on softwareupdate. This is the command line utility that makes it possible for you to do system software updates on remote machines without an administrator account. For application installations, though, we face a very different procedure, and it can get complex.

We have to backtrack a little here. Remember the discussion above about sudo? Any administrative user has sudo use by default, but since our goal is to have no local users, how can

Wrestling Alligators SIGUCCS 2003 Page 11

Page 12: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

we make it possible for a non-local, and thus by definition, non-administrative user to use sudo? Residing in the /etc directory (a special location for a UNIX machine that holds a large amount of configuration information) is a neat little file called sudoers. This is a list of users that are authorized to use sudo. I won’t try and go into depth here, because you can do a lot of tricks with this file (and it needs to be edited with something called visudo). But here is the answer: you simply add a designated user or users to the /etc/sudoers file for the master image, and then anyone logging in to any of the clones who is one of the listed users in that file can gain root access. My installations have actually made use of a Perl script that does a lookup on a remote MySQL database and uses information from that database to set up these sorts of privileges (by modifying the /etc/sudoers file on the fly). You can do this, or simply decide who in your organization will have these privileges and add that user to the sudoers file.

The sudo method gives us a way for a non-local user to become root. The next step is little more elaborate. The first thing to point out is that with no enabled local accounts (and the corresponding increase in security), the all important password file - /etc/passwd – has a different look to it. Specifically, any account that is not enabled has an asterisk in place of the password. A file that has accounts enabled with passwords looks sort of like this (only one line is shown):

root:DWa.RtYYiKLw:0:0::0:0:System Administrator:/var/root:/bin/tcsh

Now we have set the stage to make it possible to have no local accounts, and yet at least one (preferably more than one) designated user can log in against a remote authentication scheme and become root using sudo. With this, doing a “state change” can be done in one of two ways.

The first is fairly straightforward. Log in as the sudo user, become root (use sudo tcsh or sudo sh) and then issue the password change command to make the heretofore disabled root account enabled. Type passwd root and enter the new password twice. You could also do this for a known, but disabled, administrative account (I have an account with user name admin and so I would type passwd admin while root). Now, you can perform many system-level tasks. Some tasks may require you to log out and log back in to do application installations.

The second is more in keeping with the defined architecture of the OS X system. The current architecture for many parts of OS X is built around something called netinfo. This is unlike the flat file architecture used in the standard Berkeley or System V approach, and requires a number of unusual tools to read and write the netinfo database. Most of these tools have command line equivalents, so it is not difficult to “roll your own” scripts to get things going. The password file is but one small part of how the login process and authentication functions. Using the method above, you can enable a disabled account, but it is not simple to disable it. You cannot simply call up an editor such as vi and edit /etc/passwd. The changes are not recognized by the netinfo system. Instead, you have to reload any changed password file back in to netinfo using the niload command. Here’s what I do.

After setting up my master machine completely, I have several local accounts, all with passwords. The root account is enabled. When I’m ready, I start the Terminal program and issue this command (notice that trailing period!):

nidump passwd .

Wrestling Alligators SIGUCCS 2003 Page 12

Page 13: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

This produces the password file as read from the netinfo database. It will resemble the example shown earlier, but there should be a line for all of the accounts (user names) you set up, as well as several other ones that are part of the system. Now you can work with the data. First, let’s create an actual file from the command we just used:

nidump passwd . > /Users/admin/open_password_file

Now we have a file named open_password_file and it is found in /Users/admin (you can change the user name here as needed). Now we can make a copy and edit this copy to have asterisks in the password fields. Do this:

cp open_password_file closed_password_filevi closed_password_file

Carefully change all of the password fields from the hash you see to a simple asterisk - * - and save the file back out. Now, the root, admin (if you use that particular account name) and any other account you created should all have an asterisk in the password field. It might look like this:

nobody:*:-2:-2::0:0:Unprivileged User:/dev/null:/dev/nullroot:*:0:0::0:0:System Administrator:/var/root:/bin/tcshdaemon:*:1:1::0:0:System Services:/var/root:/dev/nullunknown:*:99:99::0:0:Unknown User:/dev/null:/dev/nullsmmsp:*:25:25::0:0:Sendmail User:/private/etc/mail:/dev/nullwww:*:70:70::0:0:World Wide Web Server:/Library/WebServer:/dev/nullmysql:*:74:74::0:0:MySQL Server:/dev/null:/dev/nullsshd:*:75:75::0:0:sshd Privilege separation:/var/empty:/dev/nulladmin:*:501:20::0:0:Administrator:/Users/admin:/bin/tcshcustomer:*:502:20::0:0:CIT Computer Lab User:/Users/customer:/bin/tcsh

Now we have two password files, one with the accounts enabled, the other with the account disabled. Now we have what we need to use a command line tool to disable the accounts (or re-enable them if that is required).

Since we are presumably logged in and looking at a Terminal window as root, we can simply do this:

niload -d passwd . < /Users/admin/closed_password_file

This reads our modified password file – the one that has all accounts disabled – back in to the netinfo database. Now, all the local accounts are disabled, and the only logins allowed are from those users who authenticate against the network.

This is a complex process, and you probably won’t need to do it a lot, but you should be familiar with it. One final warning – and it is an important one. Don’t forget to move those specially modified password files off of the local drive! If you don’t do this, and your security is not rock solid, a malicious user might be able to find them and run them against a cracking program! I store mine on a USB flash drive, and have developed simple shell scripts to set the password file

Wrestling Alligators SIGUCCS 2003 Page 13

Page 14: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Figure 1: Directory Access

to be open or closed. For the moment – until everything else is completely setup, leave the system with local accounts enabled.

LDAP authenticationThe matter of local versus non-local accounts depends a lot on your network infrastructure. This section talks about the authentication of non-local users against an LDAP server. There are plenty of other ways to leverage your existing infrastructure: OS X Server, Active Directory, LDAP, Novell – all of these are usable for this purpose. I am only going to cover LDAP here, though. There are numerous resources for the other options.

LDAP or Lightweight Directory Access Protocol is a widely used method to store and retrieve information about users and accounts. I chose this method because it allowed us to leverage our existing UNIX data backend easily and our transition to LDAP was well underway when I began my OS X project work.

Setting up LDAP on the OS X client is quite straightforward. There is one important caveat: you should either have control of the LDAP server yourself or be in a good working relationship with those that do! You might need frequent access to logs, or there may be a need to change or modify some of the data or the schemas used to set up the server. In any case, you are likely to want to do some careful debugging.

The first step to setting up LDAP involves the OS X utility Directory Access (/Applications/Utilities). This is a GUI interface that facilitates much of the authentication infrastructure you need for OS X. Note that this part of the paper only deals with LDAP v3. This version allows fully encrypted passwords (V2 did not) and SSL support, both essential for a secure installation.

The following steps are needed to setup LDAP authentication:

Configure Directory Access on the local machine

Create the dummy account Add the certificate to the local

machine Edit the ldap.conf file to make

the local system aware of the certificates

Configure Authentication on the client

Start Directory Access, and examine the window that appears in figure 1.

Wrestling Alligators SIGUCCS 2003 Page 14

QuickTime™ and aTIFF (Uncompressed) decompressorare needed to see this picture.

Page 15: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Figure 2: Directory Access LDAP Configuration Search Base

Figure 3: Directory Access LDAP Record Mappings

Under the Services tab, you’ll see a list of the many services you can use. My configurations turn off all services except for LDAPv3. With this service checked on and selected, click the Configure… button, then click the show Options arrow on the left. Uncheck the Use DHCP-supplied LDAP server if it is on. Now, click the New.. button. The first task is to name this configuration (I used LDAPUVM), and enter the dns name or IP address of the server. Under the pull-down menu for LDAP Mappings, select the type that agrees with your server. We use a UNIX back-end, so I choose RFC 2307 (Unix). Once you enter this, click OK (see figure 2). The dialog that appears first requires that you configure a search base suffix. This is where an LDAP query starts. You will need to get this information from your LDAP server administrator. The entry I use looks like this:

ou=people,dc=uvm,dc=edu

After you have set the search base suffix, you get the detailed configuration dialog (see figure 3), which begins on the Record Mappings pane. This is the place where you establish the links between your OS X client requesting authentication and the LDAP server. The first Record Type and Attribute in the list on the left is the Default Attribute Types. This contains only RecordName, which is set to value cn as an LDAP server attribute. Your server might use something different, so check before you enter.

The next line is the list of attributes we want returned with a query. This Users list contains, usually, only those values that we want mapped. In my project, these were set up as follows:

RecordName maps to netid (equivalent to the user login name)RealName maps to cn (the Common Name of the user)

Wrestling Alligators SIGUCCS 2003 Page 15

QuickTime™ and aTIFF (Uncompressed) decompressorare needed to see this picture.

QuickTime™ and aTIFF (Uncompressed) decompressorare needed to see this picture.

Page 16: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Figure 4: Directory Access LDAP Connections

UniqueID maps to uvmAltUID (see note below)PrimaryGroupID maps to uvmAltGID (see note below)NFSHomeDirectory maps to uvmAltHomeDir (see note below)

You will undoubtedly notice that there are three record types that are not exactly mapped to standard values: UniqueID, PrimaryGroupID & NFSHomeDirectory. This is done because we sought to not alter the baseline data being imported from the larger data stream (which includes the Student Information System and Human Resources data on a nightly basis). At the same time, we discovered, and later got confirmation from Apple, that you must have a valid UID and Home Directory in order to have a logged in user function at all. Because of these two facts, we elected to make an addition to our existing LDAP data in the form of a fixed set of three attributes that would be the same for all users. Specifically, each night that the data update runs, the update simply makes sure that every entry has these three “hard-coded” attributes. This does have the potential for security issues at the desktop of the client machine, but since this same basic approach – having all users of any open access area or lab use the same local home directory – has been in place for many years without incident, our concerns here are minimal.

Having set up the Record Types you need, you can go ahead and delete all the ones that may be there by default. The next step is then to set the connection characteristics (see figure 4). You may want to experiment with these values. We used 10-second time-out values. Note here that the ‘Encrypt using SSL’ check box is checked on. You may want to uncheck this and do some initial testing without using SSL to be sure you have everything setup correctly.

One of the implications of having all users use the same UID and Home Directory on the local machine is that they will be using the same local drive space. To make this work, you need to establish a “dummy” local account for the purposes of having a local file system space and to make sure that some of the applications that require it are able to write to the correct locations on the client machine. This is a simple matter of using the System Accounts part of System Preferences. There is an important gotcha here that you must be careful with! OS X uses an internal method to determine the numbering of the user accounts – you do not have direct control over this. This means that you must make certain that the local “dummy” account you create for this purpose has the same UID as the UID number you select in LDAP if you go this route. For example, if you choose a UID number of 503 for your modified LDAP data, then you must be sure that the local account you make also has that same UID. You can only be certain if you know the account structure on the

Wrestling Alligators SIGUCCS 2003 Page 16

QuickTime™ and aTIFF (Uncompressed) decompressorare needed to see this picture.

Page 17: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

local machine. In the case of a brand new machine, never been setup before, the account numbering starts at 501. This will be the UID for the account you create at setup time. Any additional accounts will be number from 502 on. Thus, if you simply make a single account at setup time (call it ‘admin’) and then create a dummy account (we called it ‘customer’), this second account will have a UID of 502. Our LDAP data will then require this same UID of 502.

Next, note that the account you create on the client will have a default local directory – ours is /Users/customer – and that this is the same value you must plug in to the third attribute on the LDAP server.

Finally, you are probably wondering about the GID number. This is not a required attribute for getting things to work and so could probably be left off the process. However, things being in a state of development with OS X (we are currently at 10.2.6) and given the remote possibility we might want to work with permissions at a group level on the client machines, we elected to include this item in the list of additional data. This was (somewhat arbitrarily) set to 502 as well.

Once the Record Types and attributes are setup and you create the local dummy account, you are ready to add the certificate needed to get SSL to function. The certificate is obtained from some location on your larger infrastructure, and placed in the local client directory /System/Library/OpenSSL/certs/. You can, if you like, check that things are working from the Terminal command line using the following command:

openssl s_client –connect ldap.uvm.edu:636 -showcerts You have to use your server name, of course, but this test will establish that the system can read the needed certificate without a problem.

Once the certificate is in place, you need to edit the local ldap.conf file so that the local client knows about the configuration data. The file to edit, after you make a copy, of course, is /etc/openldap/ldap.conf and should be edited to include the following lines:

HOST ldap.uvm.eduBASE dc=uvm,dc=eduTLS_CACERT /System/Library/Openssl/certs/ca-bundle.crt

Again note the specific server name and possibly the ‘BASE’ value. The certificate is now ready to use.

The last step is to configure the OS X client to use this newly added authentication method. Note that at this point, you still (should) have at least one local account, and since you cannot remove the top level NetInfo domain (the local database), you will still be allowed to log in as that local user if something goes wrong.

Wrestling Alligators SIGUCCS 2003 Page 17

Page 18: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Figure 5: Directory Access LDAP Authentication Path

Configuring the local client is very simple. With the Directory Access utility still open, click the Authentication tab. Now, click the ‘Add…’ button and the resulting window will have the object we just created available for use. Select it, and then click ‘Add’. Now your Authentication pane should include your LDAP entry as the second item to check (see figure 5). You are ready to do a live test.

If you have problems – i.e. you cannot login at all using any valid user name (except the local user), you should first try removing the SSL part of the process. If this allows a login, then you may need to examine the logs used on the LDAP server. One interesting (and sometimes annoying) problem I encountered had to do with the system date: if this date somehow changed to the date of the epoch (a special UNIX date) then things get pretty unhappy and you may see very long login times even with the local account. You should also make sure that your record mappings and attributes are correct, that the UID on the local client matches that passed in from the LDAP server, and go back over the details above if you have doubts.

Installing the softwareObviously, you will want to install all of the software needed for the client machine. This is a good time to do that. In general, I install software while logged in as the administrator of the machine. Most software installations require an administrative password anyway, and this makes the process a little easier. In general, I have not yet found any tricky installation issues. There are likely to be some bumps along the way. You may need to examine things like permissions and write-access in a few cases. Note that without the presence of Classic mode, many knotty issues simply go away. I would again strongly suggest you jettison the past and stay with the present!

Configuring what your user seesHaving set up the authentication method, you now proceed to establish the “look and feel” of the local user. This is most easily done by using that “dummy” account you created earlier. Log in as that dummy user and arrange things to suit. There may be a few odd instances where you have to twiddle things to get them just right – you may find that you have to have administrative privileges to configure something the way you want it. You can, if need be, set this account to be an administrator in order to do this, but do not forget to set the account back to a regular, non-administrative type when you are done.

Note that at this stage, you do not need to worry about users resetting things or using different values. This problem is addressed later on when we create a means by which this shared user space is effectively replaced at every login.

Wrestling Alligators SIGUCCS 2003 Page 18

QuickTime™ and aTIFF (Uncompressed) decompressorare needed to see this picture.

Page 19: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

You almost certainly will want to include the following things in your generic user configuration:

- Set the screen saver up to kick in after a reasonably short time (we use 5 minutes) and also require a password upon wake;

- Set the Energy Saver feature up with care – I allow the display to sleep but not the machine itself (so I can use the cron facility to shut the machines down at a predetermined time);

- Make sure you run every application! If you forget to do this, you may inadvertently require all subsequent users to enter a serial number or register something. Don’t forget to actually play a DVD disc;

- Set up a home page default and carefully configure your browser.

Once you have things just the way you want them, then you can log out of this account for the moment.

PrintingThe joys of printing are almost inevitably going to pose a particular and painful set of challenges for your installation. I have found that with the Macintosh and OS X, things are actually not as bad as they used to be under OS9 and Desktop Printing. In most cases, you will want to set up printers and not allow users to changes things at all. This is not as tough as it seems.

To setup the printers, use the Print Center utility and be sure to test thoroughly!

Login/logouthookOne of the nifty little parts that Apple has added in to OS X is the ability to call certain scripts at login or logout time. You may wonder why this is so special when we also have a panel available in the Login Items in System Preferences. The reason is quite simple: the Login Items belong to and are managed by the user logging in, but the scripts called through the login or logout hook apply to the system regardless. This also means that the scripts run as the call from login or logout hook run as root and so are completely in control of the entire system. A word of serious caution here: if you are careless about scripts called from the login or logout hook, you could easily reduce your OS X machine to a pile of rubble! The best way to work with this feature is to test any script thoroughly first, preferably running as a user other than root. Once you are 100% sure that your script does what it is supposed to do and nothing more, then you can add it in to the login or logout hook, If you are not comfortable in the world of shell scripting, I would suggest you use scripts that are already written for this purpose.

The basic step to getting this mechanism to work correctly is to edit the file in the /etc/ directory called ttys. Before you even think about firing up vi or emacs, though, make a copy of this file! If you make a mistake editing the master, then your machine could be toast. If you have a copy, then repairing the damage in single user mode is relatively straightforward. The way to make a copy might be apparent at this point. Use sudo (become root) and, after you have changed into the /etc/ directory, simply cp ttys ttys.ORG. Now, we have a copy of this file in its original state.

Wrestling Alligators SIGUCCS 2003 Page 19

Page 20: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Now we can go ahead and edit this file. If you are not yet fluent in vi or emacs, you can use pico, but you must make sure you call it correctly to avoid a fatal line wrapping problem that will render the file inoperable for system use. Do not use TextEdit as this will create serious problems. Below are the ways you can edit the file (again, after you make a copy).

If you use vi:

cd /etc/vi ttys

If you use emacs1:

cd /etc/emacs ttys

If you use pico:

cd /etc/pico –w ttys

Notice that we called pico using the –w flag which disables the automatic word-wrap feature and makes it possible to edit long lines.

There is actually only a single line we need to edit in the ttys file. But it’s a real doozy! Here it is in it’s original state:

console "/System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow" vt100 on secure window=/System/Library/CoreServices/WindowServer onoption="/usr/libexec/getty std.9600"

And here is what we want to edit to add a loginhook. The added section is in boldface:

console "/System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow -LoginHook /Library/Admin/cleanout.sh" vt100 on secure

1 Note that if you use emacs for a lot of tasks, you must pay close attention to file ownership issues. Emacs has an unpleasant habit of not respecting the original owner information for a file. Thus, if one has a file called test.txt owned, for example, by joeuser and proceeds to edit this file as root, then the new owner after editing is root and joeuser can no longer work with this file at all. If you list the file before you edit it, you might see this:

-rw------- 1 joeuser usr 24 Jun 09 15:14 test.txt

And after editing it as root, it looks like this:

-rw------- 1 root system 24 Jun 09 15:14 test.txt

You will need to use chown to change the ownership back to the original user. For the ttys file, it is already owned by root (and must stay that way) and no changes are needed.

Wrestling Alligators SIGUCCS 2003 Page 20

Page 21: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

window=/System/Library/CoreServices/WindowServer onoption="/usr/libexec/getty std.9600"

After you have made this change, save the file and exit the editor. What is happening here is that we are adding the –Loginhook flag to the existing call to loginwindow and passing to that the complete path to our own script that will now run at login time. If you decide you want to run the script at logout time, simply replace –LoginHook with –Logout Hook2.

Console loginSince we are already working with the /etc/ttys file, this is a good chance to add one other small change that can make a big difference: removal of the console login option. The problem is simple. OS X allows one to enter >console in the area for the username at the login window. If this is done (no password is required), then the user is dropped right into a plain console login. For most users, this could be a serious point of confusion! There is no GUI interface to rescue them. This is not in and of itself a security issue, because there really is no difference between this console and the Terminal application interface. Should you choose to disable Terminal.app and would rather your users have no access at all to this part of the system, disabling the console login is probably a pretty good idea. Here’s how we do that.

First, as noted above, be sure you have a backup copy of your /etc/ttys file. Failure to do this invites a problem. Now, edit this file (again use either vi, pico –w, or emacs). On the line of choice (we show here the modified line from above), remove the part shown in bold:

console "/System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow -LoginHook /Library/Admin/cleanout.sh" vt100 on secure window=/System/Library/CoreServices/WindowServer onoption="/usr/libexec/getty std.9600"

Notice we do not remove that last close quotation mark. Now save your file. From this point onward, both the console login option and the loginhook are operational.

You will note at this stage that our loginhook points to a script that does not yet exist on the system: /Library/Admin/cleanout.sh. We will look at this script a little later on. For now, leave things as they are.

Cron jobsUNIX systems have plenty of interesting and useful utilities to make life a little simpler. Among them is the cron facility. This is a mechanism to allow specified jobs (scripts, executables, etc.) to be executed according to certain time criteria. This can be configured to do the same thing over and over again or simply do a “one shot” deal. For details about cron, see the man page for it.

Cron uses a special little file of instructions called the crontab file, which exists for any user on the system, including root. It is possible to restrict who may and may not use cron, but that’s 2 In OS X 10.1.2 and earlier, you may also need to twiddle the Apple Menu to get users to use the correct logout mechanism. These early versions of the OS “broke” the logout hook mechanism when called this way.

Wrestling Alligators SIGUCCS 2003 Page 21

Page 22: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

more than we want to deal with here. We’re going to look at how to shut the machine down every night, something that many lab managers might like to have, and how to do system cleanup tasks at appropriate times.

Shutdown at 11:55 p.m.To do a complete system shutdown of the OS X system, we normally use the GUI and select “Shut down” from the Apple Menu. To setup a cron job to do the same thing, though, we can’t call the GUI parts of the OS. We have to use the native UNIX tools instead. There are 2: shutdown and halt. The former call has some problems in the unattended mode we want to use, so we’ll use halt instead. Halt does just that: a total stop of the system. Note that this does not have any provision for warning users that have open files. Halt stops the system abruptly. You may want to either notify users at login (I run a web browser at login that can point to a local file or a URL and display a bold warning message) or setup another cron job to run 5 minutes before the system is halted that gives users warning.

Here is how we do this. First, to get the halt command to work at all, it must be run as the root user. That means we need to be able to become root, either by logging in or use of sudo. After you become root, call the crontab editing mechanism:

crontab –e

This starts the default editor for the root user with a blank window. Now, we tell cron what to do and when:

55 23 * * * /sbin/halt

The syntax of the crontab file is very exacting. If you do a web search on crontab, you’ll get plenty to read! Our line is quite simple. The first “field” (all fields in the crontab file are separated by a space) denotes minutes after the hour, in this case 55. The next field denotes the hours or the hour of the day, in 24 hour time, which in this case is 23 or 11 pm. Thus, something will happen at 11:55 p.m.. The next 3 fields are all * which is the shorthand for “anything”. These fields are, in their respective order, the day of month, the month and the weekday. The last field is a completely specified command to run – this must include the full pathname. In our case, we are calling /sbin/halt. Put all together, our crontab line says “On any day of the week, on any month, on any day of the month, at exactly 23 hours (11 PM) and 55 minutes, run the halt command in /sbin/”. That’s pretty much all there is to it.

If we wanted to add a warning to users, we might set it up as an RTF file and put it somewhere on the system – say /Library/admin/Documents – and then call it a little earlier like this:

45 23 * * * /usr/bin/open -a /Applications/TextEdit.app/ /Library/Admin/warn.rtf

Here, we use the built-in open command with a flag to specify which application to use and open up the file named warn.rtf which might have a very loud sign that lets users know they have only so much time before everything stops.

Wrestling Alligators SIGUCCS 2003 Page 22

Page 23: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

You can use the cron facility to schedule all sorts of things: cleaning up the ‘Lost and Found’ directory is one we will add later. When you’re done, you can review your entries using the crontab command, but with the -l flag (list):

crontab –l55 23 * * * /sbin/halt45 23 * * * /usr/bin/open -a /Applications/TextEdit.app/ /Library/Admin/warn.rtf

Note that the facility is not forgiving of mistakes. You must have the syntax correct in order for it to work at all. I usually will test something by setting an arbitrary time close to the present time and then making sure it runs before I set my final periodic time.

Also, remember that each user on the system may have his or her own cron jobs unless you disallow this. Make sure you are root for system-wide calls such as halt. The administrative user may not have the power needed to do a particular task.

System cleanupFinally, note that the OS X system itself comes with a selection of pre-wired cron jobs for special maintenance use. These may or may not be important to you, but many of them are designed to run when many similar jobs on larger UNIX systems run – at 3:00 a.m.! One of the things you may want to look into is the timing of log rotation, because these logs not only can hold useful information (especially if there is a serious problem) but also can get big. If you leave the defaults in place, and do not run a 24-hour lab, then chances are the logs will never turn over, and in the event you need to read them, you will face a daunting task in scrolling!

Unlike the user account crontab, though, these special system crontab files are managed, and edited differently and are located in a different place on the system. Start by making a backup copy of the original file:

cd /etc/cp crontab crontab.ORG

Now, decide on timing. This may not be a minor decision, because the whole purpose of this system-wide “sweep” is to minimize the impact on any logged-in user. However, I elected to run these just prior to the lab closing, based on lab use and on the fact that for these particular client machines, this was not a huge CPU hog.

You may not know that this file is set to read-only by default. We must change this to edit the file:

ls –l crontab-r--r--r-- 1 root wheel 299 Jun 19 11:11 crontabchmod u+w crontabls –l crontab-rw-r--r-- 1 root wheel 299 Jun 19 11:11 crontab

Wrestling Alligators SIGUCCS 2003 Page 23

Page 24: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Edit the file using either vi, emacs or pico –w as we have suggested earlier:

vi crontab

To get the log rotation to happen at a time when the machines are on, the lines look like this (assuming you choose 11:45, 11:30 and 11:15 p.m. respectively):

#minute hour mday month wday who command…# Run daily/weekly/monthly jobs.45 23 * * * root periodic daily30 23 * * 6 root periodic weekly15 23 1 * * root periodic monthly

Note that you should not change any other lines in this file! When you are done, save and exit. Also note that the formatting is a little different than the regular crontab file, as there are additional specifications available to you. The example above includes the “header” line that labels each field. I’ve elected to run the daily job at 11:45 p.m. every day, the weekly job at 11:30 p.m. on Sunday (that’s the 6) and the monthly job on the first day of every month at 11:15 p.m.. Do not change the ‘who’ – we have to have root run these jobs.

Change the permissions back to read-only when you’re done:

ls –l crontab-rw-r--r-- 1 root wheel 299 Jun 19 11:13 crontabchmod u-w crontabls –l crontab-r--r--r-- 1 root wheel 299 Jun 19 11:13 crontab

Logout after a set idle timeThere are several other functions that are useful as cron jobs. One of the things I like to do is to have the machines log the user out of the system after a set amount of idle time. This is not an exact process, because “idle time” is almost a misnomer on a UNIX system. Ideally, idle time simply means “the user is not doing anything anymore”. Taking this at face value, I elected to simply count off a certain time interval beginning from the time that the screensaver kicks in (see the section following about how I setup the screensaver) and after that time is exceeded, log the user out.

Things got messy pretty quick! First, I discovered that there is no built-in utility to do a command line logout. My earliest tests had the machine restart, but this is really a lot more than I need. To the net! And lo and behold, Apple Developer kindly had a small piece of sample code that had the basic framework of what I needed to do: log users out. After a little bit of modification, I had a neat little executable that had no user interface and could be called at the command line. We’ll look at the script and the underlying mechanism later on.

For now, we need to set up the cron line that calls this script. Edit the root crontab file as before, and add this line:

Wrestling Alligators SIGUCCS 2003 Page 24

Page 25: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

* * * * * /Library/Admin/idleScript.app

This simply says “at any time, on any day, run the script named ‘idleScript.app’ in the ‘/Library/Admin’ directory. We will install the script and the other parts later on.

The appendix has a copy of my crontab defaults. If you follow the suggestions here, yours should look the same.

We’re done in the cron department!

Duplicating the /Users/customer folderPast practice has dictated that the client machines be refreshed fully at some regular interval. In an open access setting, this makes a lot of sense. Increasingly, however, the default configurations for many operating systems are geared toward increasingly stringent security measures, and OS X is no exception. We’ve seen that the root user has total control, and that any administrative user has the ability to install software and change settings. The typical user does not have this power. As a result, there is a lot less to worry about in terms of the local user changing the machine into a variety of your favorite vegetable!

What I am currently finding effective as a means of restoring the local user workspace and configuration is a simple restore of this specific directory tree. As noted above, all non-local accounts that log in to the OS X client share the same working space: /Users/customer. All we need to do is to have a spare, clean copy of this directory and, at some point, replace the one in use with this spare. I do this at login.

There are a few gotchas to watch out for. We’ll cover each one in turn.

The ByHosts problemThe most unusual (some might say painful!) problem in the OS X environment is the use of a hardware-linked set of preferences for a number of applications. This is not the same as the process used by something like Final Cut Pro to enforce licenses. For the most part, the applications that use this are all bundled with the new machines and so there is not an issue of license use or abuse. However, it is essential that this task be done, because if you do not do this and clone the machines, every user that logs in will have to deal with the process of having many applications think that they are being run for the first time.

This is quite straightforward in how it is setup. Each user of an OS X machine has a home directory, and in that home directory we find a ~/Library/Preferences directory. Within this we find a ByHosts directory, and this contains a number of machine specific files. The problem is how to ensure that these files are all correctly modified to work for each individual machine.

The easiest way to do this is in the cloning process itself using a post-installation script. This script simply iterates through all of the files in the ByHosts directory and replaces the master machine hardware address that shows up by default with that of the machine being cloned. We’ll cover this script and how it is used in the later section on cloning.

Wrestling Alligators SIGUCCS 2003 Page 25

Page 26: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Ditto versus cpIf you think that the issue of dual forked files went away with OS X – surprise! Not completely. For this reason, we must use the built-in ditto utility and not the standard UNIX cp (copy) command. If we don’t then some files get “dinged” and won’t work at all.

The ditto command has a good man page – be sure to read it. The syntax we use here is:

ditto –rsrcFork /source/directory/ /target/directory/

The –rsrcFork flag tells the command to “preserve resource forks and HFS meta-data”.

Making the backup copyNotwithstanding the ByHosts issue, the matter of replicating a spare copy of the local, non-administrative, shared users home directory is pretty simple.

First, decide on the backup copy location. Make a target directory for that location. I use /Users/admin/Restore for this:

mkdir /Users/admin/Restore

Now, ditto the original source directory contents into that location:

ditto –rsrcFork /Users/customer/ /Users/admin/Restore/

Check to make sure it all got there:

ls –laR /Users/admin/Restore/

There are some syntax idiosyncrasies to be aware of here. Note that if you do not already have the target directory made – i.e. there is no directory named Restore in /Users/admin/, and you issue this ditto command:

ditto –rsrcFork /Users/customer/ /Users/admin/Restore/

You will get this cryptic message:

/Users/admin/Restore/: File exists

But if you do not have the target directory already in place and issue this command:

ditto –rsrcFork /Users/customer/ /Users/admin/Restore

You will be fine. The difference is that trailing forward slash – “/” – at the end.

Wrestling Alligators SIGUCCS 2003 Page 26

Page 27: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Also note that when we check the contents using the ls command, we use the additional flags –a and –R to see both the “hidden” files as well as a recursive look to make sure all the subdirectories got there.

Now you have the foundation for a “mini-restore” process that will be able to replace the entire common shared user home directory at some point, usually at login or logout time. We’ll put the finishing touches to this later on.

Tweaking the user interfaceIn an open access situation, the ideal system presents a smooth, easy to manage interface for all users. Any user should be able to do their work, log out, and then let the next user login with a minimum of fuss and hassle. Tweaking the user interface allows us to set some things up to try and ensure that this happens.

Developer Tools & “nib”bling at partsSince one of the primary changes we want to make here is in the availability of particular menu choices, we’ll be modifying the Apple menu. While this can be done using a plain old text editor, I highly recommend that you use the tools provided in the Developer package. This is usually part of most currently shipping installations. Go ahead and do the installation. When you are done, you should find a folder called Developer at the root of the drive. Inside, you will find a lot of interesting things to explore – later!

To get started, navigate to the folder in the Developer folder called Applications. Find and run Interface Builder. This is the “human usable” way to make these kinds of changes. We’re going to modify the Apple menu. To do so, follow these steps:

1. In the Finder, navigate to System -> Library -> Frameworks -> Carbon.framework -> Versions -> A -> Frameworks -> HIToolbox.framework -> Versions -> A -> Resources -> English.lproj.

2. Find StandardMenus.nib and double click it. It should open right up with Interface Builder.

3. Make any changes you like – use care! The changes I typically make include removal of:a. ‘Get Mac OS X Software…’b. ‘System Preferences…’c. ‘Sleep’

You might want make a few other changes depending upon your situation.4. Save the file when finished – the program makes a backup of the original for you

automatically.

It is also possible to customize the Login screen. This takes more than just the Interface Builder tool; you’ll want to use Photoshop or Gimp to work the actual background images. Also be aware that the size and placement of the actual images can be pretty squirrelly, so test cautiously! In brief, one generally edits the tiff image(s) on the login screen and then makes any needed changes to the actual dialog box itself using Interface Builder. There is a fair amount of documentation found on the web for this procedure; I worked from the notes found on macosxlabs.org at this link:

Wrestling Alligators SIGUCCS 2003 Page 27

Page 28: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

http://www.macosxlabs.org/documentation/custom_loginwindow/intro.html which is very complete!

Software UpdatesOne of the things that makes OS X an interesting challenge is keeping up with all those updates! Taking care of a few critical parts will save you a lot of time later.

The most important thing here is to be certain that you uncheck all automatic updating mechanisms for the generic user. You can leave it turned on for the administrative account if you like, but having it pop up for a non-administrative user is a real nuisance. Open System Preferences, then find Software Update, and then uncheck the option under the ‘Update Software’ tab that reads ‘Automatically check for updates when you have a network connection’.

The second thing that is worth looking at here has to do with these same software updates: they can be done at the command line, and this means they can be carried out remotely! The (now) familiar terminal command line is a big help. Start with a simple man page command:

man softwareupdate

And read through it carefully. Basically, you have the option of calling this command, and then reviewing the results manually and selecting those you want to do. For direct, console access, you’d likely want to stick with the gui version (called from System Preferences). But if you maintain a far-flung network of Macs, the ability to ssh in to each, do a software update and then exit is a real timesaver.

Locking things downThe exigencies of security often seem to preclude much more than a “putting out fires” approach, so when it comes to making sure your installations are secure and as bulletproof as you can get them, taking time to review and understand the Macintosh OS X situation is important. That said, however, the reality is, of course, different! No matter how much you read and study this subject, the simple truth is that you will invariably miss something.

Start with the basics: set the open firmware passwords, secure or eliminate local accounts, disable root access. Each of these is a vital first step. Taking it further, we can do a number of things that improve the situation.

With LDAP (or other externally based) authentication to the desktop, most regular users won’t (and should not) be administrative users. Unless there is a seriously pressing need to do otherwise, this is something to avoid like the plague. Since they are not administrative users, a lot of the locking down is done for you: they can’t install software (there are a few exceptions, but these won’t install into /System); they can’t change mission-critical settings; they can’t access or delete mission-critical files. But there are things that these non-administrative users can do unless you take preventative action.

Wrestling Alligators SIGUCCS 2003 Page 28

Page 29: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Changing executable permissionsOne of the simple steps you can take is to simply reset permissions for some executable programs. This again requires root access, and is simply a matter of identifying the programs you would rather users not have access to and setting the permissions accordingly. I find that the best way to do this is to log in as a regular (generic) user and try and run as many programs as I can find! If I then discover that there is one I shouldn’t be messing with, add it to the list and change it after this testing is done.

Typically, I’ve been preventing access to these programs: Airport utilities Console Directory Access Disk Utility Installer Keychain NetInfo Manager Network Utility

Some of these may seem unnecessary – some of their functionality does depend upon supplying an administrative password. I chose to err on the side of caution here: you may elect otherwise. In any event, remember to change the permissions only for the ‘other’ category – leave ‘group’ and ‘user’ intact. At the command line, cd into the correct directory and issue the chmod command:

chmod o-rwx AirPort\ Admin\ Utility.app

And continue on with your list. You can string them all together in one single call:

chmod o-rwx AirPort\ Admin\ Utility.app Console.app

Note that we use the chmod with only the ‘o’ for the who part of this symbolic use of chmod. (Note that the ‘\’ character acts to delimit the embedded spaces in the names). You should find that the group association with these utilities is admin and, since none of your regular users are in that group (they should normally be part of the staff group unless you have directed your LDAP configuration to be otherwise), it is not necessary to set it as –ro as well. This also has advantages: when someone in the admin group does log in, they will be able to run these utilities.

Because some programs are designed to facilitate access to sensitive system data, it is probably a good idea to set these non accessible by regular users as well. The most obvious one is NetInfo, because the suite of command line utilities that accompany it provide a lot of information.

It is a good idea to make sure regular users do not have access to some of the logs and other data used by NetInfo. While it appears that these are now shipping this way by default, take a look and be sure:

ls -l /var/backups/

Wrestling Alligators SIGUCCS 2003 Page 29

Page 30: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

ls -l /var/db/netinfo/local.nidb

If the permissions include the group and other category, change it:

chmod go-rwx /var/backups/chmod go-rwx /var/db/netinfo/local.nidb

All of the little command lines utilities for netinfo use should be set to root use only:

chmod go-rwx /usr/bin/niclchmod go-rwx /usr/bin/nireportchmod go-rwx /usr/bin/niutilchmod go-rwx /usr/bin/nigrepchmod go-rwx /usr/bin/nifindchmod go-rwx /usr/bin/nidumpchmod go-rwx /usr/bin/niload

At this point, you are pretty secure in this regard. Be sure you set the NetInfo utility itself in the /Applications/Utilities folder as limited access:

chmod o-rwx NetInfo\ Manager.app

There is one odd special case: Print Center. There is also some discussion about how best to set these permissions. The problem is simple: you do not want users to be able to add or delete printers from the Print Center. But at the same time, printing works because applications are able to write to particular locations, and since these applications run as the user and not as root, there is a problem.

My solution was a basic “beat it until it yields” approach – simple to do! I wound up discovering that setting the Print Center Application to permissions that only allow root and admin group access to the application. To set these permissions, hop on the terminal, become root and type:

chmod o-rwx Print\ Center.app

Now a listing of the files in /Applications/Utilities shows this for Print Center:

ls –l drwxrwx--- 3 root admin 102 Feb 11 2003 Print Center.app

This approach has been very solid for me for a while. Another approach that has been used at Yale has the permissions set no read for anyone, eg.:

d-wx-wx-wx 3 root admin 102 Feb 11 2003 Print Center.app

This is an interesting way to do it, and while my testing involved both permission settings, I settled on the no access one. I suspect that this will be one of the oddball issues that you may

Wrestling Alligators SIGUCCS 2003 Page 30

Page 31: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

have to cope with through upgrades and your own infrastructure, so I have included that method here.

File access permissionsSimilarly, there are some files you probably do not want to have regular users have access to. Again, the built-in protections are there by virtue of regular users not being administrative users, but you may need to go a little further. Use of the chmod utility is again the route to take here. In the terminal, cd to the appropriate directory and then set the permissions as you need them.

Read-onlyIn some cases, files can (and should be) set to read-only – any user of the system can read these files. The chmod command is straightforward here, using only the o-wx symbolic syntax to do this (this leaves a file or directory as readable but no writeable or executable). Take care as you go: resetting permissions willy-nilly may produce undesirable results!

No access at allThere may be some files that you do not want regular users to even read. This is simple enough with chmod: use the o-r syntax. This is a place to exercise real restraint. Setting things non-readable could make it impossible to do certain tasks on the machine.

SetUID and SetGID programsUNIX has many special little goodies that run in one of two non-standard modes called setuid and setgid respectively. This means that, when run, the user running these programs or accessing these files is granted system access: the actual process UID is changed to that of the user owner of the file. If you think about this for a moment, you can begin to see the implications. For a program that is owned by the root user, it has the potential to allow that non-privileged user to “be” the owner (in this case, root!) This is not something you want.

It is possible – and I would encourage you – to audit your system to find all files that are configured as setuid and setgid using the UNIX find command. From the terminal, type:

find / -type f -perm +6000 -ls

The UNIX find utility is very powerful – explore it. You can save this list by sending to a named file:

find / -type f -perm +6000 –ls > mysetuidgidfiles.txt

Then you have a reference for later perusal. Common practice would suggest that, unless there is a compelling reason not to do so, the following files all be set to not allow setuid/setgid access or access by anyone other than the root user:

/usr/bin/chfn/sbin/rdump/sbin/rrestore

Wrestling Alligators SIGUCCS 2003 Page 31

Page 32: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

/usr/sbin/sliplogin/usr/bin/wall/usr/bin/write

Use the chmod command to change them:

chmod 0700 /usr/bin/chfnchmod 0700 /sbin/rdumpchmod 0700 /sbin/rrestorechmod 0700 /usr/sbin/sliploginchmod 0700 /usr/bin/wallchmod 0700 /usr/bin/write

Here we use the absolute mode in chmod in order to save a step. The 0700 sets the file to be read, write and execute only by the owner and removes the setuid bit at the same time.

You may or may not wish to take some of these suggestions. There is a veritable ocean of information about UNIX and OS X security out there on the web. My gentle suggestion is not to take it all too seriously, simply because you can literally spend all of your time working on security issues. The bottom line for me is: get to the point where all of the obvious, easy to do things are protected.

Granting privilegesOne of the challenges you will likely face is the need to perform certain kinds of privileged operations after you have deployed all your machines. Murphy’s law doesn’t really care if it’s a Mac, so you need to be prepared to deal with this situation.

If you retain local accounts, one of these will be the administrator account and you need read no further. If you do elect to limit or remove local accounts, this part may be helpful.

There are a few ways to approach this. The simple way is to designate a specific user or users that, when logged in, will have some special privileges. The most desirable privilege would use of the sudo facility. To do this, become root and at the terminal line, type:

visudo

This starts an editor (vi) that allows you to modify the /etc/sudoers file. The simple way is to add a line that is a mimic for the previous lines that has the name of the designated user. The last few lines in the default file look like this:

# User privilege specificationroot ALL=(ALL) ALL%admin ALL=(ALL) ALL

Wrestling Alligators SIGUCCS 2003 Page 32

Page 33: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

If your designated special user is user mdoe (remember – you must use the same account name as that of the person logging in based on how you configure authentication), then you could add the line:

mdoe ALL=(ALL) ALL

This allows user mdoe to become root even if the local accounts are turned off and root is disabled. There is a lot that can be done at this stage. When you have added users, exit and the editor will enforce syntactic rules (which are moot if you are simply adding a single user with full rights as shown above). If you want to explore further, man visudo is a good place to start. It is possible to configure sudoers to allow very specific operations and privileges to specific users.

Another approach that makes it feasible to grant privileges more or less dynamically is to use a special login script that checks a network based backend (typically an sql table) and allots privileges based on this listing. This is the method I currently use, and it is proving to be quite robust. In essence, a perl script receives the name of the user logging in, and queries a MySQL table. If that username is found in that table, then a list of privileges is read, and the appropriate actions are taken to get things setup. This includes, at the moment, the addition of that username to the /etc/sudoers file, the appending of that username to the /etc/sshd_config file, and the setting of the timeout value before the screensaver kicks in. This could be expanded. Note that this approach requires the installation of Developer Tools (to build applications in UNIX) and the loading of a few choice Perl modules: DBD and DBI, as well as the mysqlclient software.

One thing that cannot be done with either of these methods (assuming that local accounts are disabled), however, is the gui-based installation of applications or the altering of settings (using the gui based tools). This is because these installations require the use of a username and password of a user who is a member of the admin group. There is a workaround that affords a great deal of functionality, though, and while I am (as of the date of this tutorial) still doing testing, it appears to solve quite a few problems.

To use this method requires that the user who logs in have the ability to become root. Once that user is root, we use the netinfo command line tools to add this user to the admin group. At the terminal window, type:

niutil -appendprop / /groups/admin users <user_name>

Now, the user user_name is a member of the admin group. To remove this user from the admin group, type:

niutil -destroyval / /groups/admin users <user_name>

Use caution! Careless use of the netinfo utilities is very likely to have bizarre and undesirable effects, possibly necessitating the re-imaging of the machine!

Wrestling Alligators SIGUCCS 2003 Page 33

Page 34: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Refresh & Lost and Found at loginPerhaps the most desirable part of a managed lab is the ability to have the machines present the same experience to any user that logs in. While past practice with the Macintosh has had my managed labs run a “refresh” using RevRDist, I have not completed the needed testing and research to deploy this for OS X using a tool such as radmind or RsyncX. It is a work in progress.

However, what I do have is a very reliable, very solid method that allows the machine to do a kind of “mini-refresh” – replacing and updating the regular user home directory and all the settings – dock, etc. – at login time. It is quite simple to use and is a blessing for users.

To set up this process, we want to have completed the process of fine-tuning the user interface (see the section Configuring what your user sees above) and the other related parts needed prior to final imaging. When done, you can put the other parts in place.

Install utility scriptsIn anticipation of the making of our master disk image, we now can put in place all the little utility scripts that make this all go! Note that a number of these are path dependent from other script calls, chief among the collection found throughout this paper is that of /Library/Admin. You must create this directory – it is not a built-in part of OS X. As admin, simply type

mkdir /Library/Admin

prep.shThis is a useful utility, and lives in /private/var/root as it must be run as root to work. The listing is found in the appendix. One of the advantages it confers is to make the process of incremental changes as you develop a master image much easier and quicker. This script simply saves the typing of the ditto command used to build the restore point.

Install loginhook scriptsThe scripts used to control the actions at login time can now be put in place. We have already edited the /etc/ttys file to point to the location and name for some of these scripts – if you change the path here, make sure you change it elsewhere or the loginhook scripts will not work.

cleanout.shThis script first moves any user added files to a Lost and Found directory (which you have to create), and then restores the entire /Users/customer/ directory from the hidden spare. This method has caught all of the changes that a generic user has been able to make and is a simple and reliable way to ensure consistency.

This is also the script referred to in our modified /etc/ttys file (see the section Login/logouthook above). While you could simply replace this one with the script that does the “mini-refresh” if you elect not to use the MySQL configuration, the advantage is that you can tack on a call to some other script very easily, and avoid having to debug the master script. This script lives in /Library/Admin.

Wrestling Alligators SIGUCCS 2003 Page 34

Page 35: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

cleanhdir.shThis script (which also lives in /Library/Admin) does all the work of the “mini-refresh”. Let’s look at the script in a little detail.

The first thing I like to do is to timestamp the login:

date > /tmp/access.out

Now, it is very helpful to know who is logging in, primarily because if we want to make changes, we do not want to wipe those changes out if we logout after making the changes (as the regular user) and then back in as admin:

echo "$1 logged in." >> /tmp/access.out

if test $1 = "admin"then echo "Admin logged in for testing" > /tmp/test.outelse

So the test we do above will complete the script if the user logging in is not admin. Now, we go ahead and refresh the regular user home directory area.

Assuming you have a dynamically refreshed /etc/sudoers file, you want to update that. Privileges on /etc/sudoers are read only, so we have to change those first:

/bin/chmod u+w /etc/sudoers

And then we recopy it:

/bin/cp /etc/sudoers.master /etc/sudoers

Remember to reset the permissions:

/bin/chmod u-w /etc/sudoers

Now we recopy sshd_config – which is already set w. This too is something you do not need to do if you don’t use any sort of dynamic changing from a remote source:

/bin/cp /etc/sshd_config.master /etc/sshd_config

Originally it seemed to make sense to try and develop a listing of everything that was in the home directory, iterating through it, comparing it with the master restore directory contents and acting accordingly. It became apparent later, though, that this was overkill. If you take care to have a clean /Users/customer directory in the first place, then it is far simpler to just pull out the contents of any writeable directories there and put the content into the Lost and Found directory. That’s how I do it now.

First we do the documents folder:

Wrestling Alligators SIGUCCS 2003 Page 35

Page 36: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

/usr/bin/ditto -rsrcFork /Users/customer/Documents/ /Lost\ and\ Found

Since I put an alias in the Documents folder to help users find lost things, I did not want that to wind up in the lost and found:

/bin/rm -rf /Lost\ and\ Found/Lost\ and\ Found

Now clean up the Desktop:

/usr/bin/ditto -rsrcFork /Users/customer/Desktop/ /Lost\ and\ Found

We don't want to try and "save" the contents of the Library folder in the lost and found, so this line is commented out:

#/usr/bin/ditto -rsrcFork /Users/customer/Library/ /Lost\ and\ Found

Now we do all the rest – music, movies, pictures, public files and sites are all moved to the Lost and Found:

/usr/bin/ditto -rsrcFork /Users/customer/Movies/ /Lost\ and\ Found /usr/bin/ditto -rsrcFork /Users/customer/Music/ /Lost\ and\ Found /usr/bin/ditto -rsrcFork /Users/customer/Pictures/ /Lost\ and\ Found /usr/bin/ditto -rsrcFork /Users/customer/Public/ /Lost\ and\ Found /usr/bin/ditto -rsrcFork /Users/customer/Sites/ /Lost\ and\ Found

Finally, we go ahead and remove things in the Lost and found directory that are older than 7 days:

/usr/bin/find /Lost\ and\ Found -mtime +7 -exec /bin/rm -rf {} \;

We’ve now cleaned out anything we might want to keep, so it’s time to replace the baseline directory:

First, out with the old:

/bin/rm -rf /Users/customer/

Now we can replace everything from the master replacement found in /Users/admin/Restore. Do not have a final trailing / after 'customer' or the script fails. Note again that we use ditto and not cp:

/usr/bin/ditto -rsrcFork /Users/admin/Restore/ /Users/customer

Before we can reset permissions (which we have to do), we have to unlock Normal.dot:

/usr/sbin/Setfile -a l /Users/customer/Documents/Normal

Wrestling Alligators SIGUCCS 2003 Page 36

Page 37: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Now we reset permissions and ownership. We do this because we want to be certain that nothing here is ever owned by root:

/usr/sbin/chown -R customer:staff /Users/customer

And then we can reset the lock of Normal.dot:

/usr/sbin/Setfile -a L /Users/customer/Documents/Normal

For those not versed in shell programming, this little bit really does read ‘fi’ and “closes” the if clause found at the beginning:

fi

And remember we must add this exit signal to allow login to complete:

exit 0

This script, as you can see, does a lot of the grunt work. Again, I’d avoid adding other, completely unrelated tasks here, and instead add those calls to the calling script, cleanout.sh.

attrs.pl (for MySQL access only)I have included the text of this script here for those wishing to explore this particular option. I won’t go over the gory details. In order to get this to work, you have to install the following on the master machine first. Note that some of these installs require that you have the Developer Tools installed in order to build the product. Do that before you do anything else.

mysql client software. Available from http://www.mysql.com/downloads/mysql-4.0.html - be sure to get the package installer (it is a lot simpler).

DBI software. This is the Database Independent interface for Perl. Available from http://search.cpan.org/author/TIMB/DBI-1.38/DBI.pm - and the version may change.

DBD software. This is the driver for the MySQL Perl interface. Available from http://search.cpan.org/author/RUDY/DBD-mysql-2.9002/ - note that the versions may change quickly.

Install the above in order. The mysql client should be installed using the package installer; the DBI client is next and uses a Perl Makefile call; the DBD drive is last and does the same. You might get a failure on the DBD make test, but I’ve simply ignored that in the past and continued on.

What you must have, obviously, for this to work, is a working SQL backend. We use MySQL in production here, and so I can easily verify operation. You will have to make changes to the script to point to your database file. Also note I have used a neat little perl trick to hide a MySQL password. The line in the script that reads…

require "/var/root/Library/flags.pl";

Wrestling Alligators SIGUCCS 2003 Page 37

Page 38: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

…points to a file accessible only by root. This file loads in a username and password when the perl script runs. Flags.pl looks like this:

#!/usr/bin/perl

# Set the flags for some scripts.

$user = "<your_sql_username>";$flag = "<your_sql_username_password>";

1;

Replace the values noted. If done in this way, and if you create a mysql account that can only read the access table, you are pretty safe, even if someone manages to get all the way in. Then they know who has special privileges.

Install management scriptsNext, we install a useful management script (only one at this point!).

idleScript.appOne of the things that turned up lacking in the release of OS X was a means to determine idle time for the machine. It’s not quite as simple as you might suspect in UNIX, since there are a lot of things going on all the time.

The script I use is a modified version of one that appeared on the web about a year ago. There are many others. What happens is that we have the cron facility run this script every minute, and in the script, we try to determine if the ScreenSaver is running. If it is, then we increment a count in a file found in /tmp. When the count reaches the predetermined threshold (a number you decide), the machine logs out the current user, no matter what!

Space and time make a walk through of this entire script impractical here, but there is only one critical dependency you might have to cope with: the setting of a default value of the local variable maxtime. I set this through the return of a value from my mysql database (using the attrs.pl script which creates a file on the client at login time – /tmp/<username>). The require clause in the idleScript acts to pull in this value, and, if it is empty, reverts to the system default. You can take either approach – leave it as it is if you use the call to attrs.pl elsewhere in the loginhook, or, if you don’t do this, simply commenting out the require line and setting a default value for the local variable that it creates, mymaxtime. This is a simple edit. The script as written looks like this:

require "/tmp/$username" if -e "/tmp/$username";

You need only change it to look like this:

#require "/tmp/$username" if -e "/tmp/$username";$mymaxtime = 30;

Wrestling Alligators SIGUCCS 2003 Page 38

Page 39: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

(I used 30 as the value – you can use anything). In theory, you should not have to change this line at all. As written, the require call will not complete if that file is not present. I include the needed change here in case you do have problems and are not versed in either perl or shell scripting.

The remaining part of the script is reasonably straightforward, excepting the whole process of actually killing the ScreenSaver and getting to a logout! This has undergone a number of changes, and they seem to be based on the updates applied to OS X. Initially, with the help of a very talented and patient Systems Administrator here, we determined that the system kill call did not function correctly. At that point, we used the built in Perl kill call, and that worked fine for a while. Somewhere along the way (while I was debugging Windows problems), something subtle changed and I discovered I had to use a killall to force the system to allow the logout to complete. That is how the script is currently written, and I suspect it is unlikely to break because killall is a pretty strong dose of command.

Late in the script, you will note the line that reads:

system "/sbin/logout" || die "Unable to call logout";

The file logout is not part of OS X – I had to build this myself. Thanks to Apple Developer Services, I got lucky. I found a very simple project that served to demonstrate a particular call, removed all of the human interface parts, and compiled it. The source is shown in the appendix, and the built binary is available at http://www.uvm.edu/~dlrh/osx/ - look for the file logout and save to disk.

Configure common startup optionsYou may want to setup system-wide startup items.

Web pageOne of the things I’ve found recently is that it can be very useful to have some means to broadcast a message to any user who sits down at a lab machine. It used to be a lot of overhead to start up the locally installed web browser, and getting little files to open meant an update of some sort. New hardware doesn’t have many problems in terms of memory or space, so now I have adopted a convention to start the web browser and point to a specific URL. This page has, at this point, a caution to users that the machine will logout after a specified idle time and will automatically shut down at a certain time of day. I can use redirects after a set time. This has given us a lot of flexibility here and I highly recommend it.

Deactivate local accountsAll the various parts are now in place. We are almost ready to prepare a master image. The remaining step is optional – disabling the local accounts. If you do this, you should be sure to have a well developed, good working alternate boot device, the means to log in to the local machine and become root (use sudo). You should also have some means to access the special password files (See the section Local or Network? under the Authentication section earlier for the gory details on how to do this). Just be sure you have those files accessible somewhere.

Wrestling Alligators SIGUCCS 2003 Page 39

Page 40: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Figure 6: Carbon copy Cloner interface

Preparing the master img fileWe are now at the stage when we can prepare a master image file for use in cloning other machines. The tool of choice these days is Carbon Copy Cloner and it is very simple to use. There are a number of steps.

First, I am assuming – perhaps wrongly – that you are working with hardware that supports some sort of externally bootable device, i.e. FireWire. If you are not, then your options are very different (and may be impossible). We’ll need a bootable device that is not the local machine.

Second, once we have the bootable external device, we’ll boot to that, and run Carbon Copy Cloner.

Prepare a master boot drive on your FireWire driveOne very simple way to do this is to first boot to your master, log in as the admin user, attach the external drive, download Carbon Copy Cloner, and run it off of the mounted disk Image (you do not need to install it on your master machine.

Carbon Copy ClonerThis is a terrific product – simple, easy to use, well tested and tuned and, for educational users, it is free. Start Carbon Copy Cloner and you get the nifty little interface shown in figure 6.

To make a master bootable drive, we first select the Source Disk, which is our master disk. Then, select a Target Disk, which should be the attached external FireWire drive (If you don’t attach any external drive or have any good candidates for cloning, Carbon Copy Cloner will tell you that and exit).

Next, we set up the default preferences. Under the file menu, select Preferences and you see the dialog shown in figure 7. There are some important settings to pay attention to here.

Wrestling Alligators SIGUCCS 2003 Page 40

Page 41: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Figure 7: Carbon copy Cloner Preferences

First: in making a bootable external drive, we want to set the Target Disk option of Make bootable. Since this is a new external drive (or you have reformatted and partitioned it), you don’t need to deal with the Delete directories before overwriting option. It is a good idea, though, to check the Source Disk Option of Repair permissions before cloning.

On the right, make sure you do not check on the Create disk image on target option, as this will do just that: create a disk image file, not a bootable drive. With this option off, it doesn’t matter if the Prepare for Apple Software Restore is on or not (it may be on but dimmed).

Save these preferences, and when you are ready, click the little padlock on the main interface, enter your administrative password, and then click the Clone button. The cloning process begins. This particular one does not usually take too long, and when it’s done, you should have a bootable FireWire device.

Now that you have a bootable imaging drive, test it out. Reboot your master system, hold down the Option key, and if an odd looking interface appears, enter the Open Firmware password. Next, a series of disk icons appears, one of these being your newly minted bootable restore drive. Select it, then click on the right arrow, and it should boot to that device. Log in as administrator and, if all has gone to plan, you will see the local, internal drive mounted as well, but your external drive should be the primary boot device.

Problems at this stage can include a failure to boot the external device at all (usually with an error message), inability to select that device for booting, or the inability to get it to actually boot to the external drive. A complete failure usually means you missed something in the preferences (usually the Make bootable option) or possibly that there is problem with the drive itself. You can try reformatting the drive and then attempting to clone it again. If you cannot get the device to appear for booting using the option key method, let it boot to the internal drive, log in as administrator, and then open System Preferences and select the Startup Disk. Unless there is a problem with the drive or the FireWire connection, or you did not clone it correctly, the new drive should be visible as a startup drive.

Finally, install both Carbon Copy Cloner and NetRestore on this external drive.

Preparing an ASR READY image fileNow we are ready to actually develop our master image for use in cloning. This is really nothing more than running Carbon copy Cloner from the new bootable FireWire drive and adding several important options to the process.

Wrestling Alligators SIGUCCS 2003 Page 41

Page 42: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

One word of caution: the entire image preparation process requires, by my highly scientific calculations, about 2 to 3 times the actual final image size to succeed. In other words, if your final image is 2 gigabytes, you are likely to need a working space of between 4 and 6 gigabytes. Not knowing how big your final image will be the first time, this seems like it might be a chicken-and-egg problem. The best advice I can offer is to try and use a new drive, preferably something lie a 20 gigabyte unit. I partition my drives, reserving 2/3 or more of the total drive space for a volume called Images, the remaining piece called RESTORE_BOOT to make identification easy at boot time. Once you have done this process, it should be fairly simple to estimate size needs.

With that in mind, start Carbon Copy Cloner after booting from this external device. First select your source drive – the master image drive (the internal drive, not the external drive you booted from). Then select the target, preferably the Images partition on the FireWire drive. I suggest you avoid, if possible, using a network drive as it is already a long process.

Open the Preferences dialog, and make sure you check on the Create disk image on target option. Then, check on the ASR options choice Prepare for Apple Software Restore. For open access (lab) installations, you are unlikely to want the Run Setup Assistant after restore option. I do recommend you select the Read-only compressed option and leave the Segment size empty (the system will decide).

You do not need to include the Repair permissions before cloning option as that was done when we made our bootable external device. You do want the Make bootable option on.

When all is set, click the lock, enter the password, and then Clone. This process can take a long time. Be prepared for several hours. It should not run much more than this, however, unless your master image is really huge (like 15 gigabytes). If it runs too long (I have had reports of overnight), I would cancel and try again – something is not quite right.

When you are all done, there should be an image file on your target drive that has the naming convention <Hard Drive name>_asr.img and it should be pretty hefty in size. Note that you can double click it and open it as a drive image file, but it is read only. This is fine if you need to confirm something (like a mistake!), but don’t try and make any changes – they won’t work. If you do make a mistake and need to alter the master image, guess what? You have to do the whole thing over again! That’s why we spend so much time up front making sure all is 100% well before we clone.

Where does this file live?As noted above, you need to select your target drive with care. Both space and time are factors in the cloning process and the restore process, so you do need to make a careful decision as to where the image can go.

About 2X faster for cloning from a local deviceI have not done extensive benchmarking on the relationship between cloning sources and restore times, but informal testing suggests that placing the .img file on locally mounted media is about two times faster than on a network drive. This may vary somewhat according to image file size

Wrestling Alligators SIGUCCS 2003 Page 42

Page 43: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Figure 8: NetRestore interface

and network speed. In addition, there is the possibility of using a DVD based image (I have not yet gotten anything more than a spare utility-like image that will fit of a CD-ROM) which might be desirable in some cases.

CloningYou’ve gotten this far – the moment of truth is at hand. The next step is to clone your first Mac. This is a very simple, very configurable, and very quick process.

Boot from your Restore driveRepeating the caveat mentioned above – we are working with hardware that supports externally mounted and bootable devices (FireWire is the media of choice) – we now proceed to connect our master restore drive to a clone-to-be (with heartfelt apologies to Dolly the Sheep) and boot to this restore drive. Note that at this stage, you do not have to have the Open Firmware password set (but do not forget to set the password and the security-mode. See the section entitled Security: Open Firmware above for details.)

After booting up and logging in as administrator, start NetRestore.

NetRestoreThis is the heart of the process for cloning. It’s fast, easy, and like it’s counterpart, it is free for educational users. Start NetRestore and you should see the interface shown in figure 8.

NetRestore allows you to set up specific configurations that contain path names, image file names, etc. and make the entire process almost a matter of “one click shopping”.

To clone a new machine, we first make sure that the basic options are correctly set up. We do want to Erase Target Disk, we do (usually) want to Verify restored disk, and we do want to Set target as boot disk. You may elect to have the machine restart after cloning after you have done a number of operations.

Since this is your first cloning effort, there won’t be any configurations defined, so we will have to first plug in the values and then save that as a configuration. The simple way to do this is to first drag the source file – the disk image you created earlier – into the Source text entry area. You should see the complete path appear there.

Next, select a target drive – the local machine internal hard drive.

Now, check to make sure your options are setup the way you want them – Erase, Verify and Set….

Wrestling Alligators SIGUCCS 2003 Page 43

Page 44: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Figure 9: NetRestore Preferences

Now let’s look at the Preferences. Open the NetRestore preferences panel under the NetRestore menu and select Preferences. You should see the panel shown in figure 9.

These preferences allow you to both configure and set defaults. Note that at this point, the Default Configuration is empty. We have to set these up first.

The Default Target Options are configurable here, so you can go ahead and set these the way you want them.

Unless you are cloning from one FireWire drive to another, you do not need to work with the Buffers section at all.

The Additional Options is best left alone!

Post processing scriptsOne of the real strengths of NetRestore is the ability to do a lot of work after the cloning is done. This is the area we will examine next – the Post-action scripts.

The most useful function that these scripts can perform is to fix the ByHosts problem discussed earlier (see configuration: Duplicating the /Users/customer folder: The ByHosts problem). In addition, though, we can, at any point, add functionality to these scripts to do many other tasks. One good example that I recently had to deal with was the installation of an updated certificate for use by the LDAP authentication. Since the old, obsolete certificate was already in the master image file, I wanted to avoid doing the whole thing from scratch. Using simple shell commands, I added a section to the post processing script that simply moved the old file, and copied over the new file. This saved a lot of time and energy.

Fixing ByHostsFixing the ByHosts problem is detailed in the script in the appendix (postpWATMAIN.sh). I won’t walk through it line by line here, but instead provide an overview of how it works.

After setting the required shell parameters, the script sets up a couple of local variables, one of which is hardware specific. This one is one you must custom fit, and it has to have the hardware address of the machine you used as the master. Remember: the machine you set up for use as a master image is the one that placed a set of files in ~/Library/Preferences/ByHost which have that same hardware address. These are the files we change.

Wrestling Alligators SIGUCCS 2003 Page 44

Page 45: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Figure 9: NetRestore Configurations

This is done by iterating through a list of all those files, finding any references to the original hardware address, and then replacing it with the hardware address of the machine being imaged. When finished, all of the existing files on the machine we are cloning now have the correct hardware address.

When the hardware address is updated, we make a new copy of the restore point, so that all of the correct hardware addresses show up in all subsequent logins.

Note that the call to the Post-action script text entry box requires a full pathname. I simplified this by placing my various “flavors” of scripts used here at the root of the drive. Thus, we enter something like this:

./postpMYSCRIPT.sh

We make sure that the file postpMYSCRIPT.sh is on the root of our bootable external drive, the restore drive.

ConfigurationsWe noted earlier that it is possible to setup and save specific configurations. This is easy to do. Open the Edit configurations… option under the NetRestore menu. You should see the panel shown in figure 9.

Initially, the Config name box will be empty. You should see a list of configurations at the right, and among them will be the one you just setup, but it will have the name of the image file you chose.

To set up this as a configuration, click on the image file listed that you used. If all is well, then the path name should appear in the Volume path area, an image file name should be in the Relative path to image from volume path area. Now, enter a name for this configuration, and click the save button. Close this panel, and then re-open to check your work. If you want to, you can go back to the Preferences and select this configuration in the Default configuration pop-up menu. Now, running NetRestore will automatically “fill in the blanks” with all of the correct information.

Wrestling Alligators SIGUCCS 2003 Page 45

Page 46: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Figure 10: NetRestore post-restore actions

Post-restore actionsNetRestore has one more interesting feature: Post-restore actions. Pull up the panel shown in figure 10 under the NetRestore menu.

The most likely useful feature here is the ability to plug in your Open Firmware password. This works fine. One caveat: the password is entered as bullets, so you cannot verify what you have typed. For this reason, you might want to be very certain if you use this. I’ve avoided it on machines that I cannot take apart myself (in case I get it wrong). If I can reset the Open Firmware password myself, then this method is a useful helper.

The top field, setting the computer name, is a bit of a mystery to me. My own experience suggests that the computer name will be that of the master image file. Since this entire panel is not something you can save – i.e. it must be reset each time you run NetRestore – it problematizes the matter of setting a custom name.

All of the settings should now be in place. Go ahead and clone your first machine. Click the little padlock, enter your administrative password, and then the Restore button. Generally, the process is very quick – perhaps 5 to 15 minutes tops.

When you are all done, shut the machine down, disconnect the external drive, and restart. If you have not already done so, be sure to set (or reset) the Open firmware password and the security-mode to command. If you overlook this, it is quite possible your machine(s) will be toast in a week.

Now, test, test, test. Ideally, everything should be just perfect. Realistically, there are issues. Minor problems might be correctable with some scripting. Major problems are likely to require working on the master machine, re-cloning it, and going at it all over again. Expect to encounter a learning curve; expect to have some problems. But overall, you have the foundation of a fast, easy to use toolkit that makes Mac OS X deployment a snap.

Restoring damaged machinesIn the event you have a problem machine, you may need to re-image it. Follow the steps and procedures given in the Cloning section above.

Going furtherThis workshop has presented a detailed set of instructions to facilitate the creation and cloning of Macintosh OS X machines. There are a number of additional things you might wish to do in your journey.

Wrestling Alligators SIGUCCS 2003 Page 46

Page 47: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Remote accessMac OS X comes with ssh built in. For those not familiar, this is a secure shell program that allows a telnet-like access in a secure manner. Enabling ssh can be a real help in the deployment and maintenance of OS X, because it allows a user (or users) to access the machine remotely and do tasks such as software updates or other file maintenance procedures on a machine-by-machine basis. There are, obviously, some security issues inherent in this scheme. You will have to decide if those risks outweigh the benefits.

Ssh access is turned on using the System Preferences, then clicking the Sharing icon, and then checking on the item called Remote Access. I do not use any other of these features, and, if possible, I would recommend you avoid the rest of these as well.

As mentioned in a number of earlier sections, I have developed a method to dynamically configure the file that controls ssh access to the machines as the user logs in. This method preserves the security in a fairly strong way, because unless a specific user is logging in, the master copy of /etc/sshd_config is always set up to default to only local users (root) or members of the admin group. Since local accounts are disabled, the only way that a user can gain access when they should not is to appropriate the password of one of those named accounts.

Remote software updatesDescribed earlier under Configuration: Software Updates, enabling ssh in turn does allow you to remotely connect to a machine and do any needed software maintenance. Typing softwareupdate at a command line prompt does the same basic set of steps that take place when the full gui interface is used, with only minor differences. This alone can save you a lot of time and energy.

Full refreshOne of the goals of my project is to set up a complete refresh system for the Macinstoch, just as I have used for many years with RevRDist. I’m not there yet, but am pressing on in the research and development needed.

A few observations here about the overall philosophy of the fully refreshed machines is included. After imaging and refreshing both Macintosh and Windows machines for the past 9 years, and watching the underlying infrastructure grow and change, I think a full refresh, while a certain necessity, is not something that has to be done at every login or logout. I am gradually weaning the Windows labs I maintain away from this (once the final images are set up and tweaked as needed), and may well cut the refresh interval to a week, month or even a semester. No longer are tiny hard drives the obstacle. Security in the OS is now very tight (sometimes too tight!), making it next to impossible for users to install or otherwise attack the mission critical parts. OS X is similar; all of the UNIX security protocols are in place, and the average, non-administrative user cannot do much to break these systems. That said, I think it is likely that any full refresh option I finish on the Macintosh will only run once per week or month, possibly less.

Wrestling Alligators SIGUCCS 2003 Page 47

Page 48: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

RadmindThe refresh method that seems to hold a lot of promise is called radmind. There is a lot of support, a well developed and tested open-source product. It does not suffer some of the security challenges found in other products, and it is free.

There is a learning curve, and the current version, while well past the beta stage, is still a work in progress. While this does not in any way dissuade me from use of the product, it does allow me to step back and not feel that I have to rush in and deploy, deploy, deploy.

Good documentation and the binaries and source can be found at the web site: http://rsug.itd.umich.edu/software/radmind/

RsyncRsync is actually a fairly old UNIX only utility designed to push updates and files onto remote machines. The port for OS X is well developed, and might be worth a close look. One of the issues I found in the rsync approach centered on security and the need to develop ssh keypairs to make it possible for the client machine to run the update as root. This is a complex process. I have not pursued this particular product much. Documentation and a good starting point is found at the Mac OS X labs web site: http://www.macosxlabs.org/rsyncx/rsyncx.html

Essential reading

www.macosxlabs.org (be SURE you check the forums!)

www.bombich.com (be SURE you check the forums!)

Wrestling Alligators SIGUCCS 2003 Page 48

Page 49: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

Appendix

ScriptsLearning to write shell scripts might seem to pose a serious challenge for the veteran Mac administrator. Applescript notwithstanding, there was not much need for scripting on the older Mac OS. OS X changes that.

Don’t be afraid to try shell scripts and Perl scripts. It is not difficult to get the basics working. Don’t try this on your golden master! Find a “sandbox” to play in.

PerlPerl or Practical Extraction and Reporting Language, has been around for a while and enjoys an enormously popular following. The real power of Perl is the ease with which one can perform very complex tasks, including system calls. Learning Perl will take some time – don’t do it against a deadline unless you already are a programming wiz! But in the end, you will find it an invaluable part of your toolkit.

Start at the main web site: http://www.perl.com/

ShellUnlike Perl, simple shell scripts are a lot easier to get a quick handle on. These come in various flavors – Korn, CSH, etc., and this can have subtle effects. Get a good book on shell scripting – try O’Reilly’s UNIX in a Nutshell for some reference type material. And then practice, practice, practice.

Here are listings for the various shell and Perl scripts I use in the imaging and maintenance process.

#!/bin/sh# prep.sh

# Simple script to make it easy to do a quick ditto of the customer folder to restore folder# This script is kept in /private/var/root/# Note that the binary SetFile (from Developer Tools CD) must be installed

# Here, we reset the lock on the Normal. I’ve noted that sometimes, “Normal” is called# “Normal” and at other times, MS seems to want it be called “Normal.dot”. Your mileage# may vary. If you get errors, change the name accordingly.# We unlock this file because if you keep the master copy locked, it helps reduce# instances of macro virus problems./usr/sbin/Setfile -a l /Users/customer/Documents/Normal

# Here is where we do the work of moving the entire regulsr user directory to our backup

Wrestling Alligators SIGUCCS 2003 Page 49

Page 50: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

# location. Note that we use ditto and not cp because cp will lose some critical file data./usr/bin/ditto -rsrcFork /Users/customer/ /Users/admin/Restore

# And here we set the lock on the Normal file./usr/sbin/Setfile -a L /Users/customer/Documents/Normal

#!/bin/sh

############################################################### cleanout.sh## Purpose: called from loginhook, this script is the # jumping off point for a few others.# The first is the "housecleaner" script# The second is the privilege validation script## Author: David L.R. Houston# Date: May 2003#############################################################

# User name is passed in from the login process. This line is here for # testing purposes only.echo "Username is: " $1

# But this line is critical, so leave it here!USER=$1

# First, do the directory cleanout thing:# Commented line is useful for debugging...#/Library/Admin/cleanhdir.sh 2>/tmp/cleanhdir.out 1>&2/Library/Admin/cleanhdir.sh $USER

# Next is the check against the MySQL database if you are using that.# If you are not, then comment the line ‘/Library/Admin/attrs.pl $USER’ out as well.# Now do the perl script to check for attrbutes of this user.# Note well that the variable $USER is PASSED TO the Perl script. # One only gets this passed HERE through the loginhook action itself!# Again, the commented line is a debugging tool...#/Library/Admin/attrs.pl $USER 2>/tmp/attrs.log 1>&2/Library/Admin/attrs.pl $USER

# This is a CRITICAL PART of a shell call at login time. If this is not here, the script # never returns, and you guessed, you never get logged in!exit 0

#!/bin/sh

################################################################################### cleanhdir.sh## Purpose: This is the cleanup script. It simply replaces the# entire /Users/customer directory at some predetermined# point in the process, either startup or shutdown.## Changes:

Wrestling Alligators SIGUCCS 2003 Page 50

Page 51: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

# May 2003. Attempt to compare the contents of the directory with # the master and save user added documents to someplace.# The master list is called restore.list and is in /Library/Admin# This is not a great approach. Instead, use a selective replacement.## May 2003. We ALSO ALWAYS copy a fresh version of sudoers up to /etc. # The master fresh copy is also in /etc as /etc/sudoers.master.# We do this because the script here has two parts, and the # second part reads a master sql database that hase privileges listing,# including who can be a sudoer.## And now we refresh sshd_config for similar reasons as sudoers.## June 26 03 Added test for admin user to avoid a wipe of the /Users/customer# directory if we are in development.## Author: David L. R. Houston####################################################################################

# Test to see who is logging in.# NOTE: ROOT logins will NOT preclude home dir refresh!

# Who is this?date > /tmp/access.outecho "$1 logged in." >> /tmp/access.out

if test $1 = "admin"then echo "Admin logged in for testing" > /tmp/test.outelse

# This is not Mr. Admin, so we do it all... # We do the sudoers copy FIRST. # privs on /etc/sudoers are read only, so change those first... /bin/chmod u+w /etc/sudoers

# now recopy it... /bin/cp /etc/sudoers.master /etc/sudoers

# and set the perms... /bin/chmod u-w /etc/sudoers

# Now sshd_config - which is already set w /bin/cp /etc/sshd_config.master /etc/sshd_config

# We don't build a list. Instead, we simply ditto all the _writeable_ stuff # to /Lost & found.

# These are the writeables... # drwx------ 4 dlhousto staff 136 Apr 16 13:24 Desktop # drwx------ 7 dlhousto staff 238 May 2 15:12 Documents # drwx------ 24 dlhousto staff 816 Apr 16 13:24 Library # drwx------ 3 dlhousto staff 102 Apr 16 13:24 Movies # drwx------ 3 dlhousto staff 102 Apr 16 13:24 Music # drwx------ 3 dlhousto staff 102 Apr 16 13:24 Pictures # drwxr-xr-x 5 dlhousto staff 170 Apr 16 13:24 Public # drwxr-xr-x 4 dlhousto staff 136 Apr 16 13:24 Sites

# First we do the docs... /usr/bin/ditto -rsrcFork /Users/customer/Documents/ /Lost\ and\ Found

# But let's not keep a link to the same root dir there too!

Wrestling Alligators SIGUCCS 2003 Page 51

Page 52: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

/bin/rm -rf /Lost\ and\ Found/Lost\ and\ Found

# Then the rest... /usr/bin/ditto -rsrcFork /Users/customer/Desktop/ /Lost\ and\ Found

# We don't want to copy the Library Folder. Users MIGHT have settings here, # But we don't want to try and "save" those in L&F. #/usr/bin/ditto -rsrcFork /Users/customer/Library/ /Lost\ and\ Found

# Now do all the rest... /usr/bin/ditto -rsrcFork /Users/customer/Movies/ /Lost\ and\ Found /usr/bin/ditto -rsrcFork /Users/customer/Music/ /Lost\ and\ Found /usr/bin/ditto -rsrcFork /Users/customer/Pictures/ /Lost\ and\ Found /usr/bin/ditto -rsrcFork /Users/customer/Public/ /Lost\ and\ Found /usr/bin/ditto -rsrcFork /Users/customer/Sites/ /Lost\ and\ Found

# Finally, remove things older than 7 days... /usr/bin/find /Lost\ and\ Found -mtime +7 -exec /bin/rm -rf {} \;

# Preserving the dead stuff is now done. # Now we can replace it all wholesale...

# Now, out with the old... /bin/rm -rf /Users/customer/

# Now we can replace everything... # The master replacement is found in /Users/admin/Restore # NOTE: Do not have a final trailing / after 'customer' or script fails /usr/bin/ditto -rsrcFork /Users/admin/Restore/ /Users/customer

# Before we can reset permissions, we have to Unlock Normal.dot /usr/sbin/Setfile -a l /Users/customer/Documents/Normal

# Now we reset permissions.... /usr/sbin/chown -R customer:staff /Users/customer

# And then we reset the Lock of Normal /usr/sbin/Setfile -a L /Users/customer/Documents/Normal

fi

exit 0

#!/usr/bin/perl -w

############################################################### attrs.pl## Purpose: check the logged in user against a MySQL table # to determine what, if any, special privileges# that user should have. This is typcially for # maintenance or for lab monitoring persons.## Privileges include:# $maxtime - the maximum amount of time a user # can be logged in and idle before # being automatically logged out.# $mysudo - whether or not this particular user # can be granted local sudo privileges.## 20 June Rev:

Wrestling Alligators SIGUCCS 2003 Page 52

Page 53: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

# Write a small file with the MAXTIME value so# we do NOT have to call the MySQL table in the# idleScript.app every time it turns over.## Author: David L. R. Houston## Last Revision: 12 May 2003# 20 June 2003################################################################

# Check the username of the person logging in.# The user name is passed in from the calling shell script.$userloggedin = $ARGV[0];print "User logged in is $userloggedin\n";

# Now go read the sql table to determine privileges$netid_mt = &getOSXpriv($userloggedin);($netid,$mymaxtime,$myprivs)= split(/\:/, $netid_mt);#print "For user $username, got netid $netid and maxtime of $mymaxtime, privlist of $myprivs\n";

# Now we create a small file that holds the value of MAXTIME for this user....# We put this in /tmp and name it as the user logged in.# So if user jsmith is logged in, we find /tmp/jsmith# This file should be owned by root.if( ! -e "/tmp/$userloggedin"){

open(USERMT, "> /tmp/$userloggedin") || die "Can't open /tmp/$userloggedin for writing. \n";

print USERMT "\#\!\/usr\/bin\/perl\n\n";print USERMT "\$mymaxtime = ";print USERMT $mymaxtime;print USERMT ";\n\n";print USERMT "1;";close USERMT;

}

# Now build a privileges listing@privlist = split(/,/,$myprivs);#print "Array: @privlist\n";# How many do we have?$priv_count = @privlist;#print "Counted $priv_count privs\n";

# Now we set flags...$sudo = grep(m/sudo/,@privlist);if($sudo > 0){$mysudo = 'yes'};

$ssh = grep(m/ssh/,@privlist);if($ssh > 0){$myssh = 'yes'};

# The basic idea here is twofold:# - First, determine if the user read in from the master table via mysql has# any special privileges and if s/he does...# - Apply those privileges.# Privs might include:# - different value of MAXTIME so autologout is changed (but this is read in idlescript.app)# - If the named user can be a sudoer# If they can be a sudoer, we ASSUME that a "master" or clean copy of sudoers has been copied

Wrestling Alligators SIGUCCS 2003 Page 53

Page 54: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

# in to /etc from /etc/sudoers.master at the login, done in cleanout.sh.# Assuming that to be the case, we append this special user to the file.# Note that as of 5/13, ALL granted privs are from ONE field, comma-delimited, so # we decode that first and then act...

if($mysudo eq 'yes'){ # First we set privs on /etc/sudoers to work with it... open (SET_PRIV, "/bin/chmod u+w /etc/sudoers |") or die "Cannot set write privs for sudoers\n"; close(SET_PRIV);

# Next we open the sudoers file.... open(CUR_SUDOER, ">> /etc/sudoers");

# Now, if the user is 'yes' as sudoer, add him or her...# print "User $netid has a value of $mysudo for sudo'ing\n"; $new_line = $netid . "\tALL=(ALL) ALL\n";# print "Appending sudoers with $new_line\n"; print CUR_SUDOER $new_line;

close (CUR_SUDOER);

# Finally set the privs to normal open (SET_PRIV, "/bin/chmod u-w /etc/sudoers |") or die "Cannot set readonly privs for sudoers\n"; close(SET_PRIV);}

# Next, we see if this person should be allowed ssh access (this may not make sense)...if($myssh eq 'yes'){

# First we set privs on /etc/sshd_config to work with it... open (SET_PRIV, "/bin/chmod u+w /etc/sshd_config |") or die "Cannot set write privs for sshd_config\n"; close(SET_PRIV);

print "User $netid is being enabled for ssh\n"; # First, alter sshd_config... open(CUR_SSHDC, ">> /etc/sshd_config");

# Now add this line to that file $new_ssh_line = "AllowUsers " . $netid . "\n";# print "Appending sshd_config with $new_ssh_line\n"; print CUR_SSHDC $new_ssh_line;

close(CUR_SSHDC);

# Finally we set privs on /etc/sshd_config to normal... open (SET_PRIV, "/bin/chmod u-w /etc/sshd_config |") or die "Cannot set write privs for sshd_config\n"; close(SET_PRIV);

# Now we have appended sshd_config, but we still have to HUP it to get a reread. # Find the running process... $theUser = "root"; open(PID, "/bin/ps -axc -O user | /usr/bin/grep sshd |") or die "Unable to fork a ps $!"; while(my $line = <PID>){

#print "First one is: $line\n";# cut the trailing carriage returnchomp $line;

Wrestling Alligators SIGUCCS 2003 Page 54

Page 55: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

#print "Got line $line\n";

# Split on the spaces and get the process id....($stuff, $pid) = split(/\s+/, $line);

#DEBUG_ONLY #print "The pid: $pid. The rest of it: $stuff \n";

# Use the perl kill call, not the system one, to kill the ScreenSavermy $num_killed = kill 'HUP', $pid;

} print "found process id of $myPid\n";

}

# Now we see if there is a value in the sub-field 'login_script' and if there is,# create that file and run it...if($myloginscript ne ""){ print "Login script found: $myloginscript\n"; open(MYTMP, ">> /tmp/loginscript"); print MYTMP $myloginscript; close (MYTMP); # Now we need to try and run it... open(RUN_IT, "/bin/sh /tmp/loginscript |") or die "Cannot run the login script\n"; close (RUN_IT);}

### End of main

### Subroutines

sub getOSXpriv {

# This little routine uses DBI to access a special table maintained by # the primary Lab Manager (dlrh as of 4/03)# This table contains a list of anyone who should be exempted from the # usual timeout value. As of 4/30, it (the master table on the mysql # server) also has a field called 'maxtime' that holds the value of the # listed person's maxtime. If it is empty, then we simply use the default...# As of 5/12, this table also has a field called sudoer which, if set correctly,# will allow the appending of the /etc/sudoers file to allow that user sudo use.# As of 5/13, the entire privileges thing is changed: it is now one single text# field that contains a comma delimited list of privileges.

use DBI;

# This is a require that makes database access possible require "/var/root/Library/flags.pl";

# Create a locally scoped variable for the username passed in local ($username) = @_;

# We pass in the name we want to look up in the special table. $name = $username; $database = "CIT_LABS:webdb.uvm.edu"; $data_source = "DBI:mysql:$database";

$dbh = DBI->connect("DBI:mysql:$database", $user, $flag)|| die "Cannot open database: $database\n";

Wrestling Alligators SIGUCCS 2003 Page 55

Page 56: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

$theTable = "OSX_priv"; my $temp_handle; $temp_handle = $dbh->prepare("select * from $theTable where netid='$name'") || die "Cannot prepare"; $rv = $temp_handle->execute || die "Cannot execute";

if($rv > 0){ while(@row = $temp_handle->fetchrow_array) { if(@row > 0){# print $row[0] . " ," . $row[1] . " : " . $row[3] ."\n";# print "NetID: " . $row[5] . "\n"; # Concatenate the vals we need: netid (5), maxtime (6), priv_list (7)

# then we split them out above $mynetid = $row[5] . ":" . $row[6] . ":" . $row[7]; return $mynetid; } } } $dbh->disconnect; }

# Subroutine to determine a running application

sub isThisAppRunning { local ($appToCheck, $username) = @_; open (PROC, "ps -wwxo pid,command -U $username |" ); @proclist = <PROC>; close PROC; return grep ( /$appToCheck/i, @proclist); }

#!/usr/bin/perl -w

############################################################################################### idleScript.app## Purpose:# Script to detect kick-in of Screensaver, which happens after X mins, and then # LOG THE USER OUT of the machine# This is CHANGED from earlier incarnations which did a RESTART or halt.# Added compiled mini-app - RestartShutdownLogout downloaded from Apple Developer area# We HAVE to do this to maintain user security!# Adapted and fixed up a bit from macosx labs. dlrh, Feb 03## At a fresh boot, we need to be sure that there is no file /tmp/ticks# this file holds a count that is simply the number of times that this script is called.# Since the cron job calling it runs every minute, we have a simple minutes counter.# This allows us to have the Screen saver kick in, and then HOLD for # X number of minutes before we reboot!## Once we have a number, and we can test this to try to see if we should # reboot IF the screensaver has kicked in!# # Author: David L. R. Houston#

Wrestling Alligators SIGUCCS 2003 Page 56

Page 57: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

# Date: February, 2003## Last Revision:# June 20, 2003##############################################################################################

# Defaults:# Waterman = 15# Music Lab = 30# Aiken = 30# Set your default here as the local variable $maxtime:$maxtime = 30;

# Create a debug log if we need to...#open (DEBUG, ">> /tmp/debug.log")||die"Unable to open debug.log\n";# Or we turn it all off if we are not testing...open (DEBUG, ">> /dev/null")||die"Unable to open debug.log\n";

# Now we can do the work of the module...# If the screensaver is running, then we know we already have counted off 5 minutes, so we # check tickcount to see if an additional amount of time - $maxtime - has elapsed.# If it has, shut 'em down, mooove em out!

$username = &getUsername();

# We now use a special require in order to get the value of MAXTIME # without always consulting the OSX_priv db.# that file must be there, or we resort to the default values...require "/tmp/$username" if -e "/tmp/$username";$netid = $username;

if($mymaxtime ne ""){ $maxtime = $mymaxtime;}

# we assume, perhaps incorrectly, the /tmp will always be empty at reboot! Bad idea!# We check to see if the file is there, and if tickcount is > 5, we set it to 0

&initTickCount();

# And this special provision is true ONLY for machines that I configure, # because I will KNOW there is an account named 'admin'# We might want to avoid having the user admin or root timeout...# But as it turns out, I added an entry in the SQL db for use with netid = 'admin'if($netid eq "admin"){ $mymaxtime = -1;}# but not for user with netid of 'root'...if($netid eq "root"){ $mymaxtime = -1;}

print DEBUG "For user $username, got netid $netid and maxtime of $mymaxtime\n";print DEBUG "system has maxtime of $maxtime\n";

# Now, [if the user IS NOT FOUND in the mysql table] if the user file /tmp/$username contains # nothing, then they DO get a maxtime and a logout after $maxtime minutes. If they are found # AND have a non-null value for maxtime, then use THAT value for the timeout.

Wrestling Alligators SIGUCCS 2003 Page 57

Page 58: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

if ($mymaxtime > 0){

print DEBUG "User $netid does not get any special privs. Maxtime is $mymaxtime and machine will logout after $maxtime minutes.\n Checking for Screensaver use by $username...\n"; if(isThisAppRunning("ScreenSaver.framework", $username)) {

print DEBUG "User $username is running the Screensaver\n";

# First we see what tickcount is so far, and bump it by 1$tickcount = 0;$tickcount = &getTickCount();$tickcount = $tickcount + 1;&setTickCount($tickcount);print DEBUG "Current tickcount is $tickcount, maxtime is $maxtime and mymaxtime

is $mymaxtime\n";

# And if tickcount is greater than the max time, we log the user out!if($tickcount >= $maxtime) {

print DEBUG "Inside the tickcount >= maxtime loop, $tickcount and $maxtime\n";

# We use a file open instead of a system call to handle errors better. #open(PID, "/bin/ps -axc | /usr/bin/grep ScreenSaver |") or die "Unable to

fork a ps $!"; # Try something more exapnsive cuz we now know that PERL kill and logout

does not seem to be happy with other running alls! open(PID, "/bin/ps -axc -O user | /usr/bin/grep $username |") or die "Unable

to fork a ps $!"; # so now we should have a list of all the current USER's running apps... print "Got a list of PIDs run by $username\n"; while(my $line = <PID>){

print DEBUG "First one is: $line\n";($pid, $stuff) = split(/\s+/, $line);print DEBUG "split and got $pid and $stuff\n";

}

# We only need the PID from the ps call, but it is preceded by a space... my ($stuff, $pid); while(my $line = <PID>) {

print DEBUG "Iterating through the list of PIDs\n";print DEBUG "First line is $_\n";

# cut the trailing carriage return chomp $line;

print DEBUG "Got line $line\n";

# Split on the spaces and get the process id....($stuff, $pid) = split(/\s+/, $line);

#DEBUG_ONLY print DEBUG "The pid: $pid. The rest of it: $stuff \n";

# So we kill all in the list except a few special ones...

# Use the perl kill call, not the system one, to kill the ScreenSavermy $num_killed = kill 9, $pid;

Wrestling Alligators SIGUCCS 2003 Page 58

Page 59: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

#DEBUG_ONLY print DEBUG "I signaled $num_killed processes.\n";

} # The system kill call doesn't seem to work here... system "/usr/bin/killall -u $username" || die "Unable to kill process"; close (DEBUG);

# finally, we call the logout bit... system "/sbin/logout" || die "Unable to call logout";}

}}

close (DEBUG);

sub isThisAppRunning { local ($appToCheck, $username) = @_; open (PROC, "ps -wwxo pid,command -U $username |" ); @proclist = <PROC>; close PROC; return grep ( /$appToCheck/i, @proclist); }

sub getUsername { $username = `who | grep console | awk \'{ print \$1 }\'`; chomp $username; return $username; }

sub getTickCount { # We check to see if the file is there first if(-e "/tmp/ticks"){

# then we open and read...open (TICK, "/tmp/ticks") || die "Cannot open /tmp/ticks \n";while (<TICK>) { $tickcount = $_;}close TICK;return $tickcount;

}}

sub setTickCount { open(TICK, "> /tmp/ticks") || die "Can't open /tmp/ticks for writing. \n"; print TICK $tickcount; close TICK;}

sub initTickCount { print "Values of: tickcount of $tickcount and maxtime of $maxtime\n"; if(-e "/tmp/ticks"){ print "Found file in tmp\n";

open (TICK, "/tmp/ticks") || die "Cannot open /tmp/ticks \n"; while (<TICK>) { $tickcount = $_;

print "Read tickcount of $tickcount\n"; }

$tickcount = $tickcount * 1;$maxtime = $maxtime * 1;

print "Now have Values of: tickcount of $tickcount and maxtime of $maxtime\n";if($tickcount > $maxtime){

Wrestling Alligators SIGUCCS 2003 Page 59

Page 60: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

print "Did find tmp file and tickcount of $tickcount is greater than maxtime of $maxtime, so unlinking.\n";

unlink "/tmp/ticks"; # And we make a clean copy of the debug file.... unlink "/tmp/debug.out";}

}}

#!/bin/tcsh –f

############################################################# postpWATMAIN.sh# Post Action script for use in NetRestore# This one is built from a master machine in the Waterman Lab# dlrh. July 2003############################################################

#set echo# Post processing script to deal with the ‘ByHost’ hardware issues# We can also do other little tasks – correct mistakes etc.# This is adapted from the Bombich script

# Lab machine post-installation customization script# This script will provide a couple functions:# 1) Modify items in the /Users/customer/Library/Preferences/ByHost# to match the hardware address or host name of the current computer# 2) ditto the /Users/customer/* to /Users/admin/Restore, making the ByHost items # THERE valid as well...# BUT... the dittoing process seems to break a LOT of stuff, so we will have to # make sure we set the permissions correctly.

# We have to use a HARD CODED path to call this script in NetRestore

# The following item comes from the computer on which the master image was set up# YOU NEED TO EDIT THIS BEFORE RUNNING Restore

set masterHW = "0003934be9ea"

# Here we set some local variables…# The contents – via a listing and complete path name – of the target machine ByHost # directoryset byHostItems = `ls -A /Volumes/MacHD/Users/customer/Library/Preferences/ByHost`

# The hardware address of the machine being clonedset hwAddress = `/sbin/ifconfig en0 | grep ether | cut -d' ' -f 2 | sed 's/://g'`

# The machine hostnameset myhost = `/bin/hostname`

# Start in the right placecd /Volumes/MacHD/Users/customer/Library/Preferences/ByHost

# Iterate through each entry and change the incorrect (i.e. the master) hardware # addresses to the correct (i.e. local) hardware addresses.foreach file ($byHostItems)

if ( `echo $file | grep -c $masterHW` == "1" ) thenmv $file `echo $file | sed "s/$masterHW/$hwAddress/g"`

else if ( `echo $file | grep -c $masterHN` == "1" ) thenmv $file `echo $file | sed "s/$masterHN/$myhost/g"`

Wrestling Alligators SIGUCCS 2003 Page 60

Page 61: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

endifend

# Now update this machines Restore point directory.# First, we make sure that /Users/admin/Restore is empty, which means we have less# to worry about in redoing a master...

# Before we can do this, we have to Unlock Normal.dot/usr/sbin/Setfile -a l /Volumes/MacHD/Users/customer/Documents/Normal

# Now delete all…/bin/rm -rf /Volumes/MacHD/Users/admin/Restore/

# Having removed it, we need a new target dir.../bin/mkdir -m go-wx /Volumes/MacHD/Users/admin/Restore

# Now we ditto this.... (NOTE: this is one long line – the “\” shown is# the convention for line continucation or wrapping in UNIX text)/usr/bin/ditto -rsrcFork /Volumes/MacHD/Users/customer/\ /Volumes/MacHD/Users/admin/Restore/

# these are my crontab default values for the root crontab file:

* * * * * /Library/Admin/idleScript.app45 23 * * * /usr/bin/open -a /Applications/TextEdit.app/ /Library/Admin/warn.rtf55 23 * * * /sbin/halt50 11 1 * * /usr/bin/find /var/log/*.gz -mtime +90 -exec {} \;###NOTE – the entire project file, header file and routine are found on the web site of the author noted in the text.

#include "RestartShutdownLogout.h"#include <stdio.h>

/***************************************************** * Main ***************************************************** * Purpose: Demonstrating the SendEventToSystem functions. * Modifications: To have no user interface or interaction, and instead * to have this app called by cron/idlescript timing. 4/15/03. dlrh *****************************************************/int main(void){ //choosing arbitrary buffer size to hold input string const int bufferSize = 256; OSStatus error = noErr; char select [bufferSize]; Boolean quitnow = FALSE; /* Setting up table of choices which user can * choose from - we don't do this in this version * Instead, we simply assign the value we want. */ while (quitnow == FALSE) { /* printf("1: Restart computer\n"); * printf("2: Shutdown computer\n"); * printf("3: Logout computer\n"); * printf("4: Sleep computer\n"); * printf("q: quit program\n"); * printf("please enter choice:\n");fflush(stdout); * fgets(select, bufferSize, stdin); * printf("\n\n================\n");fflush(stdout);

Wrestling Alligators SIGUCCS 2003 Page 61

Page 62: Wrestling with Alligators: putting OSX in an open …dlrh/osx/Wrestling with Alligators.doc · Web viewWrestling with Alligators Putting OS X in an Open Access Lab (or “The Joy

* switch (select[0]) */ /* We eliminate all the CASE chouces and hardwire what we want... */ //sending logout event to system error = SendAppleEventToSystemProcess('rlgo');//kAEReallyLogout substitution done here if (error == noErr) { /* printf("Computer is going to logout!\n"); */ quitnow = TRUE; } else /* {printf("Computer wouldn't logout\nNote this function only works on MacOSX\n");} */ break; } //end while return(0);}

Wrestling Alligators SIGUCCS 2003 Page 62