Home » Learning Curve » CLIX: Legally Hacking
CLIX: Legally Hacking IIYou have to jailbreak an iPhone or an iPad to have this much fun.
You have to jailbreak an iPhone or an iPad to have this much fun. And we all know how Big Brother Steve feels about that. Even though the courts declared it to be completely legal. Then too you might get a Rick Astley desktop wallpaper. But what if you're more into Samantha Fox?
There certainly are advantages to using a 'real' operating system even today.
'Mise en Place'
You need a few tools open to begin hacking away.
- CLIX. Open a new CLIX document window. Perhaps save it already for safety's sake. Choose a name and location all by yourself.
- Terminal.app. This is easiest in the beginning as you experiment with commands. Don't know where to find it? Download Xfile or look in /Applications/Utilities.
- Knowledge of how the system's 'manpage' readouts work. You don't use your scroll bar - only arrow up, arrow down, space, and 'q'.
- Your wits and your hacker attitude.
With everything in place, you're ready to start. Try to make useful commands.
Checking virtual memory: systems slow down as virtual memory on disk builds up. This slowdown may be noticeable. There can come a time when your best recourse is to reboot.
Navigate in Terminal to /private/var/vm. (This is easier with Xfile.) You'll see a 'sleep image' along with your swap file(s).
The swap files are your virtual memory - what the system uses when it's running out of RAM. Hard drives are slower than memory chips; and it takes time and number crunching to keep 'swapping' things in and out. So there's a lot of (relatively slow) disk activity where there's normally little or none at all as everything still fits in your RAM (fresh boot).
The system starts you out with a 64 MB swapfile ('swapfile0') on boot. Your swap will expand as your system sees the need for it. The next swap file ('swapfile1') will be the same size. After that, things go ballistic pretty fast. Soon you can be carrying around several gig of swap files. And that's when things can start to really slow down.
That's not an ideal system but it's the system you have. David Cutler's approach is a lot simpler and makes more sense: start by allocating a swap file equal in size to primary (RAM) memory and tack on a few MB for internal bookkeeping. (This system also makes process generation a lot faster. But that's another story entirely.)
Your system will at any rate have a single swap file on startup. You can see this by burrowing down to /private/var/vm with Xfile and then opening Terminal there. (The 'test drive' version of Xfile might not have this feature enabled; you either purchase the registered version or make do without. Few things are really free.)
Once at the command line in the correct directory, you issue the following command.
$ ls
You might get back something like this after a cold boot.
sleepimage swapfile0
After a while, it might look something like this. Perhaps you've run your browser? And Adobe Flash?
sleepimage swapfile0 swapfile1
The command ls lists the contents of directories. You just used ls in its most primitive form. It only lists the files present. It doesn't tell you anything about them. But a check for some of the opportunities with that tool may help. And it might be nice to be reminded of the disk space they take.
There's no built-in help with ls. Try it.
$ ls --help
ls: illegal option -- -
usage: ls [-ABCFGHLOPRSTUWabcdefghiklmnopqrstuwx1] [file ...]
So you try a manpage. That sure is a lot of shit.
$ man ls
LS(1) BSD General Commands Manual LS(1)
NAME
ls -- list directory contents
SYNOPSIS
ls [-ABCFGHLOPRSTUW@abcdefghiklmnopqrstuwx1] [file ...]
DESCRIPTION
For each operand that names a file of a type other than directory, ls
displays its name as well as any requested, associated information. For
each operand that names a file of type directory, ls displays the names
of files contained within that directory, as well as any requested, asso-
ciated information.
If no operands are given, the contents of the current directory are dis-
played. If more than one operand is given, non-directory operands are
displayed first; directory and non-directory operands are sorted sepa-
rately and in lexicographical order.
The following options are available:
-@ Display extended attribute keys and sizes in long (-l) output.
-1 (The numeric digit ``one''.) Force output to be one entry per
line. This is the default when output is not to a terminal.
-A List all entries except for . and ... Always set for the super-
user.
-a Include directory entries whose names begin with a dot (.).
-B Force printing of non-printable characters (as defined by
ctype(3) and current locale settings) in file names as \xxx,
where xxx is the numeric value of the character in octal.
-b As -B, but use C escape codes whenever possible.
-C Force multi-column output; this is the default when output is to
a terminal.
-c Use time when file status was last changed for sorting (-t) or
long printing (-l).
-d Directories are listed as plain files (not searched recursively).
-e Print the Access Control List (ACL) associated with the file, if
present, in long (-l) output.
-F Display a slash (`/') immediately after each pathname that is a
directory, an asterisk (`*') after each that is executable, an at
sign (`@') after each symbolic link, an equals sign (`=') after
each socket, a percent sign (`%') after each whiteout, and a ver-
tical bar (`|') after each that is a FIFO.
-f Output is not sorted. This option turns on the -a option.
-G Enable colorized output. This option is equivalent to defining
CLICOLOR in the environment. (See below.)
-g This option is only available for compatibility with POSIX; it is
used to display the group name in the long (-l) format output
(the owner name is suppressed).
-H Symbolic links on the command line are followed. This option is
assumed if none of the -F, -d, or -l options are specified.
-h When used with the -l option, use unit suffixes: Byte, Kilobyte,
Megabyte, Gigabyte, Terabyte and Petabyte in order to reduce the
number of digits to three or less using base 2 for sizes.
-i For each file, print the file's file serial number (inode num-
ber).
-k If the -s option is specified, print the file size allocation in
kilobytes, not blocks. This option overrides the environment
variable BLOCKSIZE.
-L Follow all symbolic links to final target and list the file or
directory the link references rather than the link itself. This
option cancels the -P option.
-l (The lowercase letter ``ell''.) List in long format. (See
below.) If the output is to a terminal, a total sum for all the
file sizes is output on a line before the long listing.
-m Stream output format; list files across the page, separated by
commas.
-n Display user and group IDs numerically, rather than converting to
a user or group name in a long (-l) output. This option turns on
the -l option.
-O Include the file flags in a long (-l) output.
-o List in long format, but omit the group id.
-P If argument is a symbolic link, list the link itself rather than
the object the link references. This option cancels the -H and
-L options.
-p Write a slash (`/') after each filename if that file is a direc-
tory.
-q Force printing of non-graphic characters in file names as the
character `?'; this is the default when output is to a terminal.
-R Recursively list subdirectories encountered.
-r Reverse the order of the sort to get reverse lexicographical
order or the oldest entries first (or largest files last, if com-
bined with sort by size
-S Sort files by size
-s Display the number of file system blocks actually used by each
file, in units of 512 bytes, where partial units are rounded up
to the next integer value. If the output is to a terminal, a
total sum for all the file sizes is output on a line before the
listing. The environment variable BLOCKSIZE overrides the unit
size of 512 bytes.
-T When used with the -l (lowercase letter ``ell'') option, display
complete time information for the file, including month, day,
hour, minute, second, and year.
-t Sort by time modified (most recently modified first) before sort-
ing the operands by lexicographical order.
-u Use time of last access, instead of last modification of the file
for sorting (-t) or long printing (-l).
-U Use time of file creation, instead of last modification for sort-
ing (-t) or long output (-l).
-v Force unedited printing of non-graphic characters; this is the
default when output is not to a terminal.
-W Display whiteouts when scanning directories. (-S) flag).
-w Force raw printing of non-printable characters. This is the
default when output is not to a terminal.
-x The same as -C, except that the multi-column output is produced
with entries sorted across, rather than down, the columns.
The -1, -C, -x, and -l options all override each other; the last one
specified determines the format used.
The -c and -u options override each other; the last one specified deter-
mines the file time used.
The -B, -b, -w, and -q options all override each other; the last one
specified determines the format used for non-printable characters.
The -H, -L and -P options all override each other (either partially or
fully); they are applied in the order specified.
By default, ls lists one entry per line to standard output; the excep-
tions are to terminals or when the -C or -x options are specified.
File information is displayed with one or more s separating the
information associated with the -i, -s, and -l options.
The Long Format
If the -l option is given, the following information is displayed for
each file: file mode, number of links, owner name, group name, number of
bytes in the file, abbreviated month, day-of-month file was last modi-
fied, hour file last modified, minute file last modified, and the path-
name. In addition, for each directory whose contents are displayed, the
total number of 512-byte blocks used by the files in the directory is
displayed on a line by itself, immediately before the information for the
files in the directory. If the file or directory has extended
attributes, the permissions field printed by the -l option is followed by
a '@' character. Otherwise, if the file or directory has extended secu-
rity information (such as an access control list), the permissions field
printed by the -l option is followed by a '+' character.
If the modification time of the file is more than 6 months in the past or
future, then the year of the last modification is displayed in place of
the hour and minute fields.
If the owner or group names are not a known user or group name, or the -n
option is given, the numeric ID's are displayed.
If the file is a character special or block special file, the major and
minor device numbers for the file are displayed in the size field. If
the file is a symbolic link, the pathname of the linked-to file is pre-
ceded by ``->''.
The file mode printed under the -l option consists of the entry type,
owner permissions, and group permissions. The entry type character
describes the type of file, as follows:
b Block special file.
c Character special file.
d Directory.
l Symbolic link.
s Socket link.
p FIFO.
- Regular file.
The next three fields are three characters each: owner permissions, group
permissions, and other permissions. Each field has three character posi-
tions:
1. If r, the file is readable; if -, it is not readable.
2. If w, the file is writable; if -, it is not writable.
3. The first of the following that applies:
S If in the owner permissions, the file is not exe-
cutable and set-user-ID mode is set. If in the
group permissions, the file is not executable and
set-group-ID mode is set.
s If in the owner permissions, the file is exe-
cutable and set-user-ID mode is set. If in the
group permissions, the file is executable and set-
group-ID mode is set.
x The file is executable or the directory is search-
able.
- The file is neither readable, writable, exe-
cutable, nor set-user-ID nor set-group-ID mode,
nor sticky. (See below.)
These next two apply only to the third character in the last
group (other permissions).
T The sticky bit is set (mode 1000), but not execute
or search permission. (See chmod(1) or
sticky(8).)
t The sticky bit is set (mode 1000), and is search-
able or executable. (See chmod(1) or sticky(8).)
EXAMPLES
The following is how to do an ls listing sorted by increasing size
ls -lrS
DIAGNOSTICS
The ls utility exits 0 on success, and >0 if an error occurs.
ENVIRONMENT
The following environment variables affect the execution of ls:
BLOCKSIZE If the environment variable BLOCKSIZE is set, the block
counts (see -s) will be displayed in units of that size
block.
CLICOLOR Use ANSI color sequences to distinguish file types. See
LSCOLORS below. In addition to the file types mentioned
in the -F option some extra attributes (setuid bit set,
etc.) are also displayed. The colorization is dependent
on a terminal type with the proper termcap(5) capabili-
ties. The default ``cons25'' console has the proper
capabilities, but to display the colors in an xterm(1),
for example, the TERM variable must be set to
``xterm-color''. Other terminal types may require simi-
lar adjustments. Colorization is silently disabled if
the output isn't directed to a terminal unless the
CLICOLOR_FORCE variable is defined.
CLICOLOR_FORCE Color sequences are normally disabled if the output isn't
directed to a terminal. This can be overridden by set-
ting this flag. The TERM variable still needs to refer-
ence a color capable terminal however otherwise it is not
possible to determine which color sequences to use.
COLUMNS If this variable contains a string representing a decimal
integer, it is used as the column position width for dis-
playing multiple-text-column output. The ls utility cal-
culates how many pathname text columns to display based
on the width provided. (See -C and -x.)
LANG The locale to use when determining the order of day and
month in the long -l format output. See environ(7) for
more information.
LSCOLORS The value of this variable describes what color to use
for which attribute when colors are enabled with
CLICOLOR. This string is a concatenation of pairs of the
format fb, where f is the foreground color and b is the
background color.
The color designators are as follows:
a black
b red
c green
d brown
e blue
f magenta
g cyan
h light grey
A bold black, usually shows up as dark grey
B bold red
C bold green
D bold brown, usually shows up as yellow
E bold blue
F bold magenta
G bold cyan
H bold light grey; looks like bright white
x default foreground or background
Note that the above are standard ANSI colors. The actual
display may differ depending on the color capabilities of
the terminal in use.
The order of the attributes are as follows:
1. directory
2. symbolic link
3. socket
4. pipe
5. executable
6. block special
7. character special
8. executable with setuid bit set
9. executable with setgid bit set
10. directory writable to others, with sticky bit
11. directory writable to others, without sticky
bit
The default is "exfxcxdxbxegedabagacad", i.e. blue fore-
ground and default background for regular directories,
black foreground and red background for setuid executa-
bles, etc.
LS_COLWIDTHS If this variable is set, it is considered to be a colon-
delimited list of minimum column widths. Unreasonable
and insufficient widths are ignored (thus zero signifies
a dynamically sized column). Not all columns have
changeable widths. The fields are, in order: inode,
block count, number of links, user name, group name,
flags, file size, file name.
TERM The CLICOLOR functionality depends on a terminal type
with color capabilities.
TZ The timezone to use when displaying dates. See
environ(7) for more information.
COMPATIBILITY
The group field is now automatically included in the long listing for
files in order to be compatible with the IEEE Std 1003.2 (``POSIX.2'')
specification.
LEGACY DESCRIPTION
In legacy mode, the -f option does not turn on the -a option and the -g,
-n, and -o options do not turn on the -l option.
Also, the -o option causes the file flags to be included in a long (-l)
output; there is no -O option.
When -H is specified (and not overridden by -L or -P) and a file argument
is a symlink that resolves to a non-directory file, the output will
reflect the nature of the link, rather than that of the file. In legacy
operation, the output will describe the file.
For more information about legacy mode, see compat(5).
SEE ALSO
chflags(1), chmod(1), sort(1), xterm(1), compat(5), termcap(5),
symlink(7), sticky(8)
STANDARDS
The ls utility conforms to IEEE Std 1003.1-2001 (``POSIX.1'').
HISTORY
An ls command appeared in Version 1 AT&T UNIX.
BUGS
To maintain backward compatibility, the relationships between the many
options are quite complex.
BSD May 19, 2002 BSD
Yep, that sure is a lot of shit. But that's what hacking's about. For ls is one of the most powerful commands in the Unix arsenal. And it's said that if you understand ls, then you understand Unix. (It's been said by the engineers at Rixstep. They should know.)
So what do you add to ls to find out what's wasted on swap? This part is important.
-l (The lowercase letter ``ell''.) List in long format. (See
below.) If the output is to a terminal, a total sum for all the
file sizes is output on a line before the long listing.
Try it.
$ ls -l
total 2228224
-rw------T 1 root wheel 1073741824 May 9 13:55 sleepimage
-rw------- 1 root wheel 67108864 May 8 22:33 swapfile0
Now you can see the sizes in the centre of your readout.
You're going to leave 'sleepimage' alone. You could remove it and your system should be fine, but you'd see it regenerated in no time. (The system updates it continually - it's a complete map of your RAM.) And with a single swap file you're sitting good.
Play around a bit more (with Xcode, Interface Builder, Firefox, or anything from Adobe) and you'll get something like this.
$ ls -l
total 2359296
-rw------T 1 root wheel 1073741824 May 9 13:55 sleepimage
-rw------- 1 root wheel 67108864 May 8 22:33 swapfile0
-rw------- 1 root wheel 67108864 May 9 16:09 swapfile1
Perhaps you don't want the 'sleepimage' listed all the time? Efficiency being the word?
$ ls -l swapfile*
-rw------- 1 root wheel 67108864 May 8 22:33 swapfile0
-rw------- 1 root wheel 67108864 May 9 16:09 swapfile1
Now you got rid of that 'total' too. Things are improving. But perhaps you want to go the other way - list everything?
-a Include directory entries whose names begin with a dot (.).
Try it.
$ ls -al
total 2359296
drwxr-xr-x 5 root wheel 170 May 8 22:45 .
drwxr-xr-x 26 root wheel 884 Sep 14 2009 ..
-rw------T 1 root wheel 1073741824 May 9 13:55 sleepimage
-rw------- 1 root wheel 67108864 May 8 22:33 swapfile0
-rw------- 1 root wheel 67108864 May 9 16:09 swapfile1
There's a lot of nice juicy info there. Sizes, dates, ownership - and the two 'dot' directories.
One of the above commands is bound to suit your tastes. So it's time to make a CLIX command.
- Open a blank CLIX command sheet. This is the 'Add' command off the 'Edit' menu.
- Give the command a title. (Any title. This can be changed later. It can all be changed later.)
- Give it a 'category'. The category is entirely arbitrary. It's up to you. CLIX will use a secondary sort on this column if you're sorting by the first ('title') column so it pays to be consistent.
- Add a description. Or not. Again: it's entirely up to you. And it can be changed later.
- Add the command line. This is very important - and you can't use localised versions anymore: you have to use full paths. But a bit of a help: /var is actually a symlink that resolves to /private/var so you can save yourself a bit of typing. See the illustration below.
- Run the command once before clicking 'save' so you know it works correctly. You're not running much risk you'll wreck something at this stage if you type it wrong. So don't be afraid.
- Save the command to the file and save the file to disk once it's running correctly.
Additional Assistance
CLIX can help you quite a lot in your hacking. Double clicks and the option key are your friends. Open that command again ('Edit' from the 'Edit' menu) and try option-double-clicking things on that sheet. You should find that you don't get a reaction unless you're clicking inside the 'command line' field. Some double clicks will yield only the following.
But double-click 'ls' and you'll see something different.
'ls' is a Unix command aka a Unix program file aka a Unix utility in Bell Labs speak or a 'tool' in Apple speak. It's pretty easy to find on disk as well. Still got your Terminal open?
$ whereis ls
/bin/ls
So you could use the 'ls' command on itself.
$ /bin/ls /bin/ls
/bin/ls
Or for more info:
$ /bin/ls -l /bin/ls
-r-xr-xr-x 1 root wheel 80688 Jul 14 2009 /bin/ls
Back to work. Time to find something else that's useful. Listing the contents of /private/tmp can be useful at times. Some applications leave junk behind there. This is normally cleaned out at every reboot but still and all. You use the same procedure as last time - you simply want to list the contents. A hint: even though /tmp is also a symlink like /var, you have to use the full /private/tmp path. (Perhaps you'll be able to explain that after a while.)
Applications will normally use their own directories under /tmp. But the ones in the illustration above aren't to be messed with. The same goes for the socket file 'icssuis501'. Don't touch them.
OS X has more than /tmp today for storing temporary files and caches. Most of these files are generated by the system. Try the following command.
$ ls -lR /var/folders
There are some hairy subdirectories there. Ignore the ones that give you 'permission denied'. Look only at the ones where you get to see something.
And here's something you may not have seen before. (And you won't have unless you're using Xfile.) It's the collection of 'device files' built by your system at each startup.
$ ls -alR /dev
The 'R' (upper case) again makes the listing a recursive one. You might see something funny at the tail end of that listing.
/dev/fd/3:
ls: 3: Not a directory
ls: 4: directory causes a cycle
Yup, that means Apple are up to some funky stuff in there. Go back a bit further and you may see something else suspicious.
/dev/fd:
total 0
crw--w---- 1 rixstep tty 16, 0 May 9 20:26 0
crw--w---- 1 rixstep tty 16, 0 May 9 20:26 1
crw--w---- 1 rixstep tty 16, 0 May 9 20:26 2
dr-------- 15 rixstep staff 510 May 1 2010 3
dr--r--r-- 1 root wheel 0 May 9 17:56 4
Suspicious? Yes. There aren't any 'dot' directories. List the same thing with Xfile and you'll get something else; list it again with GDE and you'll get something else again. Funky stuff. There are several levels of file listing APIs in Unix - Apple are putting in a bit of their own non-portable code between them.
You'll notice as well they have comma separated values instead of the standard size field. These values are the major and minor device numbers. They show up in the ACP framework info sheet as well - but hardly anywhere else.
The 'inode'
Unix has a clever thing Apple can't handle: the hard link.
Not to say Apple engineers haven't struggled with this and/or done the best they can, but when you're told HFS will simply not go away then you're pretty much stuck in it.
One of Ken Thompson's many brilliant ideas was that directories should contain no more than filenames and hooks into volume control blocks. Further: volume control blocks shouldn't contain file names.
This is an efficient proposal but it also offers more than perhaps one originally imagined. For if volume control blocks don't have file names, then it's theoretically possible for multiple file paths to point to the same information in the volume control block. In other words: you can have multiple names for the same file.
This turns out to have several benefits. You can do more 'legal hacking' with CLIX to see some of these benefits.
Navigate in Terminal to /bin. Do this either with Xfile or by typing the path in on your own ('cd /bin''). Do a long listing.
$ ls -al /bin
total 8640
drwxr-xr-x 39 root wheel 1326 Mar 30 2010 .
drwxrwxr-t 31 root admin 1122 May 20 15:57 ..
-r-xr-xr-x 2 root wheel 63184 May 18 2009 [
-rwxr-xr-x 1 root wheel 1346544 Feb 11 2010 bash
-r-xr-xr-x 1 root wheel 44272 May 18 2009 cat
-r-xr-xr-x 1 root wheel 62656 Jul 14 2009 chmod
-r-xr-xr-x 1 root wheel 57632 Jul 14 2009 cp
-rwxr-xr-x 2 root wheel 767200 Feb 11 2010 csh
-r-xr-xr-x 1 root wheel 80848 May 18 2009 date
-r-xr-xr-x 1 root wheel 60992 Jul 14 2009 dd
-r-xr-xr-x 1 root wheel 48368 Jul 14 2009 df
-r-xr-xr-x 1 root wheel 50816 May 19 2009 domainname
-r-xr-xr-x 1 root wheel 50704 May 18 2009 echo
-r-xr-xr-x 1 root wheel 117504 May 18 2009 ed
-r-xr-xr-x 1 root wheel 67552 May 18 2009 expr
-r-xr-xr-x 1 root wheel 50816 May 18 2009 hostname
-r-xr-xr-x 1 root wheel 51024 May 18 2009 kill
-r-xr-xr-x 1 root wheel 2186880 May 19 2009 ksh
-r-xr-xr-x 1 root wheel 246720 Feb 11 2010 launchctl
-r-xr-xr-x 2 root wheel 39552 Jul 14 2009 link
-r-xr-xr-x 2 root wheel 39552 Jul 14 2009 ln
-r-xr-xr-x 1 root wheel 80688 Jul 14 2009 ls
-r-xr-xr-x 1 root wheel 35072 Jul 14 2009 mkdir
-r-xr-xr-x 1 root wheel 44848 Jul 14 2009 mv
-r-xr-xr-x 1 root wheel 238576 Jul 14 2009 pax
-r-sr-xr-x 1 root wheel 134816 May 18 2009 ps
-r-xr-xr-x 1 root wheel 50784 May 18 2009 pwd
-r-sr-xr-x 1 root wheel 93376 May 19 2009 rcp
-r-xr-xr-x 2 root wheel 44448 Jul 14 2009 rm
-r-xr-xr-x 1 root wheel 34624 Jul 14 2009 rmdir
-r-xr-xr-x 1 root wheel 1346624 Feb 11 2010 sh
-r-xr-xr-x 1 root wheel 50752 May 18 2009 sleep
-r-xr-xr-x 1 root wheel 88704 May 18 2009 stty
-r-xr-xr-x 1 root wheel 50512 Feb 11 2010 sync
-rwxr-xr-x 2 root wheel 767200 Feb 11 2010 tcsh
-r-xr-xr-x 2 root wheel 63184 May 18 2009 test
-r-xr-xr-x 2 root wheel 44448 Jul 14 2009 unlink
-r-xr-xr-x 1 root wheel 50864 Feb 11 2010 wait4path
-rwxr-xr-x 1 root wheel 1597200 May 11 2009 zsh
Now you might - if you're industrious - calculate the actual disk blocks used by each of those files and see if the total is 8640. But there's an easier way to see if something's awry here.
-i For each file, print the file's file serial number (inode num-
ber).
The inode is a number that uniquely identifies a file on a volume. No two files can have the same inode. HFS actually discards inodes after they've been used and ultimately 'rolls over' when it reaches the highest possible value and looks for free ones the second time around. (But it didn't always do this. Something Apple had to fix fast for OS X Server. Ouch.)
So supposing files in /bin are not unique, you can perform a new listing with the '-i' switch added.
$ ls -ail /bin
total 8640
24031 drwxr-xr-x 39 root wheel 1326 Mar 30 2010 .
2 drwxrwxr-t 31 root admin 1122 May 20 15:57 ..
25655 -r-xr-xr-x 2 root wheel 63184 May 18 2009 [
2693806 -rwxr-xr-x 1 root wheel 1346544 Feb 11 2010 bash
25804 -r-xr-xr-x 1 root wheel 44272 May 18 2009 cat
24717 -r-xr-xr-x 1 root wheel 62656 Jul 14 2009 chmod
24718 -r-xr-xr-x 1 root wheel 57632 Jul 14 2009 cp
2693807 -rwxr-xr-x 2 root wheel 767200 Feb 11 2010 csh
25656 -r-xr-xr-x 1 root wheel 80848 May 18 2009 date
24719 -r-xr-xr-x 1 root wheel 60992 Jul 14 2009 dd
24720 -r-xr-xr-x 1 root wheel 48368 Jul 14 2009 df
25635 -r-xr-xr-x 1 root wheel 50816 May 19 2009 domainname
25657 -r-xr-xr-x 1 root wheel 50704 May 18 2009 echo
25805 -r-xr-xr-x 1 root wheel 117504 May 18 2009 ed
25658 -r-xr-xr-x 1 root wheel 67552 May 18 2009 expr
25659 -r-xr-xr-x 1 root wheel 50816 May 18 2009 hostname
25660 -r-xr-xr-x 1 root wheel 51024 May 18 2009 kill
24921 -r-xr-xr-x 1 root wheel 2186880 May 19 2009 ksh
2693808 -r-xr-xr-x 1 root wheel 246720 Feb 11 2010 launchctl
24721 -r-xr-xr-x 2 root wheel 39552 Jul 14 2009 link
24721 -r-xr-xr-x 2 root wheel 39552 Jul 14 2009 ln
24724 -r-xr-xr-x 1 root wheel 80688 Jul 14 2009 ls
24725 -r-xr-xr-x 1 root wheel 35072 Jul 14 2009 mkdir
24726 -r-xr-xr-x 1 root wheel 44848 Jul 14 2009 mv
24727 -r-xr-xr-x 1 root wheel 238576 Jul 14 2009 pax
24032 -r-sr-xr-x 1 root wheel 134816 May 18 2009 ps
25661 -r-xr-xr-x 1 root wheel 50784 May 18 2009 pwd
25636 -r-sr-xr-x 1 root wheel 93376 May 19 2009 rcp
24728 -r-xr-xr-x 2 root wheel 44448 Jul 14 2009 rm
24729 -r-xr-xr-x 1 root wheel 34624 Jul 14 2009 rmdir
2693809 -r-xr-xr-x 1 root wheel 1346624 Feb 11 2010 sh
25662 -r-xr-xr-x 1 root wheel 50752 May 18 2009 sleep
24033 -r-xr-xr-x 1 root wheel 88704 May 18 2009 stty
2693810 -r-xr-xr-x 1 root wheel 50512 Feb 11 2010 sync
2693807 -rwxr-xr-x 2 root wheel 767200 Feb 11 2010 tcsh
25655 -r-xr-xr-x 2 root wheel 63184 May 18 2009 test
24728 -r-xr-xr-x 2 root wheel 44448 Jul 14 2009 unlink
2693813 -r-xr-xr-x 1 root wheel 50864 Feb 11 2010 wait4path
26148 -rwxr-xr-x 1 root wheel 1597200 May 11 2009 zsh
The inodes are listed in the leftmost column. This information, together with what used to be in the second but is now in the third column, should give you all you need to know. The third column is namely the number of links.
Directories always have at least two links - to '.' and '..'. The link count is comparable to Apple's HFS 'valence' field. But HFS doesn't have the 'dot' directories and so the valence should differ by 2.
Regular files that have a link count greater than one are hard linked (multi-linked in Apple parlance). Go through your latest listing and see which files are multi-linked and see if you can locate their 'alter egos'. Note: a hard link to a file need not be in the same directory; it can be anywhere on the same volume.
You should find four (4) pairs of multi-linked files.
[ | test | csh | tcsh | link | ln | rm | unlink |
So why the hard links?
[ and test are the invention of Steve Bourne who built the original sh shell (command interpreter). csh and tcsh are both the same 'shell' based on the original work at UC Berkeley. But the program behaves differently depending on the name you use to start it.
All Unix (C) programs get a list of 'arguments' used to invoke them; the very first argument is the path to the program itself. So csh/tcsh can see what was used to start things up and adjust behaviour accordingly.
Does this mean there are two programs in one? That doesn't sound particularly efficient. But no, it means there are certain features of the one program that will not be available in the other. And vice versa. So the technique actually cuts down on use of disk space and make lives a lot easier across the board.
link and ln are another such example. Check out the manpage for either and you'll see they respond to different syntax.
LN(1) BSD General Commands Manual LN(1)
NAME
link, ln -- make links
SYNOPSIS
ln [-Ffhinsv] source_file [target_file]
ln [-Ffhinsv] source_file ... target_dir
link source_file target_file
link is greatly simplified. See the end of the file for more of a clue.
STANDARDS
The ln utility conforms to IEEE Std 1003.2-1992 (``POSIX.2'').
The simplified link command conforms to Version 2 of the Single UNIX
Specification (``SUSv2'').
Then a bit above you'll find this.
When the utility is called as link, exactly two arguments must be sup-
plied, neither of which may specify a directory. No options may be sup-
plied in this simple mode of operation, which performs a link(2) opera-
tion using the two passed arguments.
So link is a bit of a 'Mickey Mouse' version of the real thing. (Note ln can create both hard links and symbolic links.)
The final pair is rm and unlink. Here too there's a difference in functionality depending on how you access the program.
RM(1) BSD General Commands Manual RM(1)
NAME
rm, unlink -- remove directory entries
SYNOPSIS
rm [-dfiPRrvW] file ...
unlink file
DESCRIPTION
The rm utility attempts to remove the non-directory type files specified
on the command line. If the permissions of the file do not permit writ-
ing, and the standard input device is a terminal, the user is prompted
(on the standard error output) for confirmation.
The options are as follows:
-d Attempt to remove directories as well as other types of
files.
-f Attempt to remove the files without prompting for confirma-
tion, regardless of the file's permissions. If the file does
not exist, do not display a diagnostic message or modify the
exit status to reflect an error. The -f option overrides any
previous -i options.
-i Request confirmation before attempting to remove each file,
regardless of the file's permissions, or whether or not the
standard input device is a terminal. The -i option overrides
any previous -f options.
-P Overwrite regular files before deleting them. Files are
overwritten three times, first with the byte pattern 0xff,
then 0x00, and then 0xff again, before they are deleted.
-R Attempt to remove the file hierarchy rooted in each file
argument. The -R option implies the -d option. If the -i
option is specified, the user is prompted for confirmation
before each directory's contents are processed (as well as
before the attempt is made to remove the directory). If the
user does not respond affirmatively, the file hierarchy
rooted in that directory is skipped.
-r Equivalent to -R.
-v Be verbose when deleting files, showing them as they are
removed.
-W Attempt to undelete the named files. Currently, this option
can only be used to recover files covered by whiteouts.
The rm utility removes symbolic links, not the files referenced by the
links.
It is an error to attempt to remove the files ``.'' or ``..''.
When the utility is called as unlink, only one argument, which must not
be a directory, may be supplied. No options may be supplied in this sim-
ple mode of operation, which performs an unlink(2) operation on the
passed argument.
The rm utility exits 0 if all of the named files or file hierarchies were
removed, or if the -f option was specified and all of the existing files
or file hierarchies were removed. If an error occurs, rm exits with a
value >0.
NOTE
The rm command uses getopt(3) to parse its arguments, which allows it to
accept the `--' option which will cause it to stop processing flag
options at that point. This will allow the removal of file names that
begin with a dash (`-'). For example:
rm -- -filename
The same behavior can be obtained by using an absolute or relative path
reference. For example:
rm /home/user/-filename
rm ./-filename
SEE ALSO
rmdir(1), undelete(2), unlink(2), fts(3), getopt(3), symlink(7)
BUGS
The -P option assumes that the underlying file system is a fixed-block
file system. In addition, only regular files are overwritten, other
types of files are not.
COMPATIBILITY
The rm utility differs from historical implementations in that the -f
option only masks attempts to remove non-existent files instead of mask-
ing a large variety of errors. The -v option is non-standard and its use
in scripts is not recommended.
Also, historical BSD implementations prompted on the standard output, not
the standard error output.
STANDARDS
The rm command is almost IEEE Std 1003.2 (``POSIX.2'') compatible, except
that POSIX requires rm to act like rmdir(1) when the file specified is a
directory. This implementation requires the -d option if such behavior
is desired. This follows the historical behavior of rm with respect to
directories.
The simplified unlink command conforms to Version 2 of the Single UNIX
Specification (``SUSv2'').
HISTORY
A rm command appeared in Version 1 AT&T UNIX.
BSD January 28, 1999 BSD
Again there's both a 'grownup' version (rm) and a 'Mickey Mouse version' (unlink) available.
The simplified unlink command conforms to Version 2 of the Single UNIX
Specification (``SUSv2'').
Both versions seem to be capable of performing the basic operation - removing a link to ('unlinking') a file.
Neither rm nor unlink remove a file from disk - all they do is remove a link. The file system itself will do this once the link count gets to zero. The file remains as long as there's still a link to it somewhere. All rm and unlink do is remove a file name from a directory - and that in turn gets the file system to decrement the link count.
Kernel Messages
The following command requires sudo. sudo was developed for OpenBSD but has since propagated to other BSDs as well. sudo gives you a means of escalating your privileges to root without actually enabling the root account. And that's a Good Thing™.
You normally have to be a member of the admin group to use sudo. (The first registered user on a system is a member.)
You use sudo by simply prefacing your command with the word. You're prompted for (what's normally) your admin password and then your command runs.
dmesg is a program that displays your system message buffer. You see this if you start your system in 'single user mode'; otherwise it's hidden. Try running it without sudo.
$ dmesg
Unable to obtain kernel buffer: Operation not permitted
usage: sudo dmesg
So try running it with sudo instead. (And no, you're not going to harm your computer no matter what you do.)
$ sudo dmesg
Password:
IOAPIC: Version 0x20 Vectors 64:87
ACPI: System State [S0 S3 S4 S5] (S3)
mbinit: done (64 MB memory set for mbuf pool)
Waiting on IOProviderClassIOResourcesIOResourceMatchboot-uuid-media
com.apple.AppleFSCompressionTypeZlib load succeeded
AppleIntelCPUPowerManagementClient: ready
Got boot device = IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/SATA@1F,2/AppleAHCI/PRT2@2/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/FUJITSU MHW2120BH Media/IOGUIDPartitionScheme/Untitled@4
BSD root: disk0s4, major 14, minor 4
[Bluetooth::CSRHIDTransition] switchToHCIMode (legacy)
[Bluetooth::CSRHIDTransition] transition complete.
CSRUSBBluetoothHCIController::setupHardware super returned 0
AppleIntelCPUPowerManagement: initialization complete
Waiting for DSMOS...
IPv6 packet filtering initialized, default to accept, logging disabled
jnl: disk0s2: journal start/end pointers reset! (jnl 0x30e3e04; s 0x1aa200 e 0x1aa200)
Atheros: mac 12.2 phy 8.1 radio 12.0
Previous Shutdown Cause: 0
Warning - kext com.apple.iokit.CHUDProf has immediate dependencies on both com.apple.kernel* and com.apple.kpi.* components; use only one style.
AppleYukon2: Marvell Yukon Gigabit Adapter 88E8053 Singleport Copper SA
AppleYukon2: RxRingSize <= 1024, TxRingSize 256, RX_MAX_LE 1024, TX_MAX_LE 768, ST_MAX_LE 3328
DSMOS has arrived
IO80211Controller::dataLinkLayerAttachComplete(): adding AppleEFINVRAM notification
en1: Supported channels 1 2 3 4 5 6 7 8 9 10 11 12 13 36 40 44 48 52 56 60 64 100 104 108 112 116 120 124 128 132 136 140
AirPort: Link Up on en1
AirPort: RSN handshake complete on en1
hibernate image path: /var/vm/sleepimage
sizeof(IOHibernateImageHeader) == 512
Opened file /var/vm/sleepimage, size 1073741824, partition base 0xe05cc0000, maxio 400000
hibernate image major 14, minor 4, blocksize 512, pollers 5
hibernate_alloc_pages flags 00000000, gobbling 0 pages
hibernate_page_list_setall start
hibernate_page_list_setall time: 88 ms
pages 232335, wire 39100, act 42998, inact 595, spec 81, zf 2406, throt 0, could discard act 19333 inact 33143 purgeable 731 spec 93948
hibernate_page_list_setall found pageCount 85180
IOHibernatePollerOpen, ml_get_interrupts_enabled 0
IOHibernatePollerOpen(0)
writing 84957 pages
image1Size 73775104
PMStats: Hibernate write took 4542 ms
all time: 4542 ms, comp time: 637 ms, deco time: 0 ms,
image 151337984, uncompressed 348311552 (85037), compressed 150473776 (43%), sum1 173a5b4c, sum2 5f51712a
hibernate_write_image done(0)
sleep
Wake reason = EC LID0
System Wake
Previous Sleep Cause: 0
getWOW_PARAMETERS: Can't set wow params. Wow is not supported
getWOW_PARAMETERS: Can't set wow params. Wow is not supported
dmesg doesn't cache the entire buffer, only the most recent 4 KB (4096 bytes) of it. So the beginning of your readout might be a bit funky. The buffer's initialised on startup and should show you interesting things about your system (and even engineering shortcomings).
Use of sudo is always wrought with danger. But running your system as if you own it is even worse. Escalating to root only as needed spares your system damage from interlopers and also casual input error on your own behalf.
Be careful when testing commands that use sudo: try them first without sudo if at all possible. Use predefined CLIX commands. Be sure your admin password is secure and change it regularly.
sudo and CLIX
A website long forgotten posted a note shortly after the arrival of 10.6 Snow Leopard that CLIX wasn't compatible with the new system. The syntax for use of sudo in similar situations had changed. The program didn't need to change at all. Herp derp.
And it had nothing to do with Snow Leopard either. Herp derp. It had to do with a new version of sudo which Apple still hadn't passed onto their users. See the pertinent section of sudo's manpage.
-S The -S (stdin) option causes sudo to read the password from
the standard input instead of the terminal device.
As CLIX is not Terminal, this is where sudo will read your password. The manpage for sudo reveals a lot about how your system works, so it's a good read when you have the time.
$ man sudo
SUDO(8) MAINTENANCE COMMANDS SUDO(8)
NAME
sudo - execute a command as another user
SYNOPSIS
sudo [-n] -h | -K | -k | -L | -V | -v
sudo -l[l] [-AnS] [-g groupname|#gid] [-U username] [-u username|#uid]
[command]
sudo [-AbEHnPS] [-C fd] [-g groupname|#gid] [-p prompt]
[-u username|#uid] [VAR=value] [-i | -s] [command]
sudoedit [-AnS] [-C fd] [-g groupname|#gid] [-p prompt]
[-u username|#uid] file ...
DESCRIPTION
sudo allows a permitted user to execute a command as the superuser or
another user, as specified in the sudoers file. The real and effective
uid and gid are set to match those of the target user as specified in
the passwd file and the group vector is initialized based on the group
file (unless the -P option was specified). If the invoking user is
root or if the target user is the same as the invoking user, no
password is required. Otherwise, sudo requires that users authenticate
themselves with a password by default (NOTE: in the default
configuration this is the user's password, not the root password).
Once a user has been authenticated, a timestamp is updated and the user
may then use sudo without a password for a short period of time (5
minutes unless overridden in sudoers).
When invoked as sudoedit, the -e option (described below), is implied.
sudo determines who is an authorized user by consulting the file
/private/etc//sudoers. By running sudo with the -v option, a user can
update the time stamp without running a command. The password prompt
itself will also time out if the user's password is not entered within
0 minutes (unless overridden via sudoers).
If a user who is not listed in the sudoers file tries to run a command
via sudo, mail is sent to the proper authorities, as defined at
configure time or in the sudoers file (defaults to root). Note that
the mail will not be sent if an unauthorized user tries to run sudo
with the -l or -v option. This allows users to determine for
themselves whether or not they are allowed to use sudo.
If sudo is run by root and the SUDO_USER environment variable is set,
sudo will use this value to determine who the actual user is. This can
be used by a user to log commands through sudo even when a root shell
has been invoked. It also allows the -e option to remain useful even
when being run via a sudo-run script or program. Note however, that
the sudoers lookup is still done for root, not the user specified by
SUDO_USER.
sudo can log both successful and unsuccessful attempts (as well as
errors) to syslog(3), a log file, or both. By default sudo will log
via syslog(3) but this is changeable at configure time or via the
sudoers file.
OPTIONS
sudo accepts the following command line options:
-A Normally, if sudo requires a password, it will read it from
the current terminal. If the -A (askpass) option is
specified, a helper program is executed to read the user's
password and output the password to the standard output.
If the SUDO_ASKPASS environment variable is set, it
specifies the path to the helper program. Otherwise, the
value specified by the askpass option in sudoers(5) is
used.
-b The -b (background) option tells sudo to run the given
command in the background. Note that if you use the -b
option you cannot use shell job control to manipulate the
process.
-C fd Normally, sudo will close all open file descriptors other
than standard input, standard output and standard error.
The -C (close from) option allows the user to specify a
starting point above the standard error (file descriptor
three). Values less than three are not permitted. This
option is only available if the administrator has enabled
the closefrom_override option in sudoers(5).
-E The -E (preserve environment) option will override the
env_reset option in sudoers(5)). It is only available when
either the matching command has the SETENV tag or the
setenv option is set in sudoers(5).
-e The -e (edit) option indicates that, instead of running a
command, the user wishes to edit one or more files. In
lieu of a command, the string "sudoedit" is used when
consulting the sudoers file. If the user is authorized by
sudoers the following steps are taken:
1. Temporary copies are made of the files to be edited
with the owner set to the invoking user.
2. The editor specified by the SUDO_EDITOR, VISUAL or
EDITOR environment variables is run to edit the
temporary files. If none of SUDO_EDITOR, VISUAL or
EDITOR are set, the first program listed in the editor
sudoers variable is used.
3. If they have been modified, the temporary files are
copied back to their original location and the
temporary versions are removed.
If the specified file does not exist, it will be created.
Note that unlike most commands run by sudo, the editor is
run with the invoking user's environment unmodified. If,
for some reason, sudo is unable to update a file with its
edited version, the user will receive a warning and the
edited copy will remain in a temporary file.
-g group Normally, sudo sets the primary group to the one specified
by the passwd database for the user the command is being
run as (by default, root). The -g (group) option causes
sudo to run the specified command with the primary group
set to group. To specify a gid instead of a group name,
use #gid. When running commands as a gid, many shells
require that the '#' be escaped with a backslash ('\'). If
no -u option is specified, the command will be run as the
invoking user (not root). In either case, the primary
group will be set to group.
-H The -H (HOME) option sets the HOME environment variable to
the homedir of the target user (root by default) as
specified in passwd(5). By default, sudo does not modify
HOME (see set_home and always_set_home in sudoers(5)).
-h The -h (help) option causes sudo to print a usage message
and exit.
-i [command]
The -i (simulate initial login) option runs the shell
specified in the passwd(5) entry of the target user as a
login shell. This means that login-specific resource files
such as .profile or .login will be read by the shell. If a
command is specified, it is passed to the shell for
execution. Otherwise, an interactive shell is executed.
sudo attempts to change to that user's home directory
before running the shell. It also initializes the
environment, leaving DISPLAY and TERM unchanged, setting
HOME, SHELL, USER, LOGNAME, and PATH, as well as the
contents of /etc/environment on Linux and AIX systems. All
other environment variables are removed.
-K The -K (sure kill) option is like -k except that it removes
the user's timestamp entirely. Like -k, this option does
not require a password.
-k The -k (kill) option to sudo invalidates the user's
timestamp by setting the time on it to the Epoch. The next
time sudo is run a password will be required. This option
does not require a password and was added to allow a user
to revoke sudo permissions from a .logout file.
-L The -L (list defaults) option will list out the parameters
that may be set in a Defaults line along with a short
description for each. This option is useful in conjunction
with grep(1).
-l[l] [command]
If no command is specified, the -l (list) option will list
the allowed (and forbidden) commands for the invoking user
(or the user specified by the -U option) on the current
host. If a command is specified and is permitted by
sudoers, the fully-qualified path to the command is
displayed along with any command line arguments. If
command is specified but not allowed, sudo will exit with a
status value of 1. If the -l option is specified with an l
argument (i.e. -ll), or if -l is specified multiple times,
a longer list format is used.
-n The -n (non-interactive) option prevents sudo from
prompting the user for a password. If a password is
required for the command to run, sudo will display an error
messages and exit.
-P The -P (preserve group vector) option causes sudo to
preserve the invoking user's group vector unaltered. By
default, sudo will initialize the group vector to the list
of groups the target user is in. The real and effective
group IDs, however, are still set to match the target user.
-p prompt The -p (prompt) option allows you to override the default
password prompt and use a custom one. The following
percent (`%') escapes are supported:
%H expanded to the local hostname including the domain
name (on if the machine's hostname is fully qualified
or the fqdn sudoers option is set)
%h expanded to the local hostname without the domain name
%p expanded to the user whose password is being asked for
(respects the rootpw, targetpw and runaspw flags in
sudoers)
%U expanded to the login name of the user the command will
be run as (defaults to root)
%u expanded to the invoking user's login name
%% two consecutive % characters are collapsed into a
single % character
The prompt specified by the -p option will override the
system password prompt on systems that support PAM unless
the passprompt_override flag is disabled in sudoers.
-S The -S (stdin) option causes sudo to read the password from
the standard input instead of the terminal device.
-s [command]
The -s (shell) option runs the shell specified by the SHELL
environment variable if it is set or the shell as specified
in passwd(5). If a command is specified, it is passed to
the shell for execution. Otherwise, an interactive shell
is executed.
-U user The -U (other user) option is used in conjunction with the
-l option to specify the user whose privileges should be
listed. Only root or a user with sudo ALL on the current
host may use this option.
-u user The -u (user) option causes sudo to run the specified
command as a user other than root. To specify a uid
instead of a user name, use #uid. When running commands as
a uid, many shells require that the '#' be escaped with a
backslash ('\'). Note that if the targetpw Defaults option
is set (see sudoers(5)) it is not possible to run commands
with a uid not listed in the password database.
-V The -V (version) option causes sudo to print the version
number and exit. If the invoking user is already root the
-V option will print out a list of the defaults sudo was
compiled with as well as the machine's local network
addresses.
-v If given the -v (validate) option, sudo will update the
user's timestamp, prompting for the user's password if
necessary. This extends the sudo timeout for another 5
minutes (or whatever the timeout is set to in sudoers) but
does not run a command.
-- The -- option indicates that sudo should stop processing
command line arguments. It is most useful in conjunction
with the -s option.
Environment variables to be set for the command may also be passed on
the command line in the form of VAR=value, e.g.
LD_LIBRARY_PATH=/usr/local/pkg/lib. Variables passed on the command
line are subject to the same restrictions as normal environment
variables with one important exception. If the setenv option is set in
sudoers, the command to be run has the SETENV tag set or the command
matched is ALL, the user may set variables that would overwise be
forbidden. See sudoers(5) for more information.
RETURN VALUES
Upon successful execution of a program, the exit status from sudo will
simply be the exit status of the program that was executed.
Otherwise, sudo quits with an exit value of 1 if there is a
configuration/permission problem or if sudo cannot execute the given
command. In the latter case the error string is printed to stderr. If
sudo cannot stat(2) one or more entries in the user's PATH an error is
printed on stderr. (If the directory does not exist or if it is not
really a directory, the entry is ignored and no error is printed.)
This should not happen under normal circumstances. The most common
reason for stat(2) to return "permission denied" is if you are running
an automounter and one of the directories in your PATH is on a machine
that is currently unreachable.
SECURITY NOTES
sudo tries to be safe when executing external commands.
There are two distinct ways to deal with environment variables. By
default, the env_reset sudoers option is enabled. This causes commands
to be executed with a minimal environment containing TERM, PATH, HOME,
SHELL, LOGNAME, USER and USERNAME in addition to variables from the
invoking process permitted by the env_check and env_keep sudoers
options. There is effectively a whitelist for environment variables.
If, however, the env_reset option is disabled in sudoers, any variables
not explicitly denied by the env_check and env_delete options are
inherited from the invoking process. In this case, env_check and
env_delete behave like a blacklist. Since it is not possible to
blacklist all potentially dangerous environment variables, use of the
default env_reset behavior is encouraged.
In all cases, environment variables with a value beginning with () are
removed as they could be interpreted as bash functions. The list of
environment variables that sudo allows or denies is contained in the
output of sudo -V when run as root. This list reflects the built-in
defaults, which may be overridden in sudoers.
On Mac OS X, sudoers has been configured to only whitelist a small set
of environment variables by default. See the sudoers file for more
information.
Note that the dynamic linker on most operating systems will remove
variables that can control dynamic linking from the environment of
setuid executables, including sudo. Depending on the operating system
this may include _RLD*, DYLD_*, LD_*, LDR_*, LIBPATH, SHLIB_PATH, and
others. These type of variables are removed from the environment
before sudo even begins execution and, as such, it is not possible for
sudo to preserve them.
To prevent command spoofing, sudo checks "." and "" (both denoting
current directory) last when searching for a command in the user's PATH
(if one or both are in the PATH). Note, however, that the actual PATH
environment variable is not modified and is passed unchanged to the
program that sudo executes.
sudo will check the ownership of its timestamp directory (/var/db/sudo
by default) and ignore the directory's contents if it is not owned by
root or if it is writable by a user other than root. On systems that
allow non-root users to give away files via chown(2), if the timestamp
directory is located in a directory writable by anyone (e.g., /tmp), it
is possible for a user to create the timestamp directory before sudo is
run. However, because sudo checks the ownership and mode of the
directory and its contents, the only damage that can be done is to
"hide" files by putting them in the timestamp dir. This is unlikely to
happen since once the timestamp dir is owned by root and inaccessible
by any other user, the user placing files there would be unable to get
them back out. To get around this issue you can use a directory that
is not world-writable for the timestamps (/var/adm/sudo for instance)
or create /var/db/sudo with the appropriate owner (root) and
permissions (0700) in the system startup files.
sudo will not honor timestamps set far in the future. Timestamps with
a date greater than current_time + 2 * TIMEOUT will be ignored and sudo
will log and complain. This is done to keep a user from creating
his/her own timestamp with a bogus date on systems that allow users to
give away files.
Please note that sudo will normally only log the command it explicitly
runs. If a user runs a command such as sudo su or sudo sh, subsequent
commands run from that shell will not be logged, nor will sudo's access
control affect them. The same is true for commands that offer shell
escapes (including most editors). Because of this, care must be taken
when giving users access to commands via sudo to verify that the
command does not inadvertently give the user an effective root shell.
For more information, please see the PREVENTING SHELL ESCAPES section
in sudoers(5).
ENVIRONMENT
sudo utilizes the following environment variables:
EDITOR Default editor to use in -e (sudoedit) mode if neither
SUDO_EDITOR nor VISUAL is set
HOME In -s or -H mode (or if sudo was configured with the
--enable-shell-sets-home option), set to homedir of the
target user
PATH Set to a sane value if the secure_path sudoers option
is set.
SHELL Used to determine shell to run with -s option
SUDO_ASKPASS Specifies the path to a helper program used to read the
password if no terminal is available or if the -A
option is specified.
SUDO_COMMAND Set to the command run by sudo
SUDO_EDITOR Default editor to use in -e (sudoedit) mode
SUDO_GID Set to the group ID of the user who invoked sudo
SUDO_PROMPT Used as the default password prompt
SUDO_PS1 If set, PS1 will be set to its value for the program
being run
SUDO_UID Set to the user ID of the user who invoked sudo
SUDO_USER Set to the login of the user who invoked sudo
USER Set to the target user (root unless the -u option is
specified)
VISUAL Default editor to use in -e (sudoedit) mode if
SUDO_EDITOR is not set
FILES
/private/etc//sudoers List of who can run what
/var/db/sudo Directory containing timestamps
/etc/environment Initial environment for -i mode on Linux and
AIX
EXAMPLES
Note: the following examples assume suitable sudoers(5) entries.
To get a file listing of an unreadable directory:
$ sudo ls /usr/local/protected
To list the home directory of user yazza on a machine where the file
system holding ~yazza is not exported as root:
$ sudo -u yazza ls ~yazza
To edit the index.html file as user www:
$ sudo -u www vi ~www/htdocs/index.html
To shutdown a machine:
$ sudo shutdown -r +15 "quick reboot"
To make a usage listing of the directories in the /home partition.
Note that this runs the commands in a sub-shell to make the cd and file
redirection work.
$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"
SEE ALSO
grep(1), su(1), stat(2), passwd(5), sudoers(5), visudo(8)
AUTHORS
Many people have worked on sudo over the years; this version consists
of code written primarily by:
Todd C. Miller
See the HISTORY file in the sudo distribution or visit
http://www.sudo.ws/sudo/history.html for a short history of sudo.
CAVEATS
There is no easy way to prevent a user from gaining a root shell if
that user is allowed to run arbitrary commands via sudo. Also, many
programs (such as editors) allow the user to run commands via shell
escapes, thus avoiding sudo's checks. However, on most systems it is
possible to prevent shell escapes with sudo's noexec functionality.
See the sudoers(5) manual for details.
It is not meaningful to run the cd command directly via sudo, e.g.,
$ sudo cd /usr/local/protected
since when the command exits the parent process (your shell) will still
be the same. Please see the EXAMPLES section for more information.
If users have sudo ALL there is nothing to prevent them from creating
their own program that gives them a root shell regardless of any '!'
elements in the user specification.
Running shell scripts via sudo can expose the same kernel bugs that
make setuid shell scripts unsafe on some operating systems (if your OS
has a /dev/fd/ directory, setuid shell scripts are generally safe).
BUGS
If you feel you have found a bug in sudo, please submit a bug report at
http://www.sudo.ws/sudo/bugs/
SUPPORT
Limited free support is available via the sudo-users mailing list, see
http://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search
the archives.
DISCLAIMER
sudo is provided ``AS IS'' and any express or implied warranties,
including, but not limited to, the implied warranties of
merchantability and fitness for a particular purpose are disclaimed.
See the LICENSE file distributed with sudo or
http://www.sudo.ws/sudo/license.html for complete details.
1.7.0 November 15, 2008 SUDO(8)
See the 'CAVEATS' section for two important insights. The first: a word of real world caution.
CAVEATS
There is no easy way to prevent a user from gaining a root shell if
that user is allowed to run arbitrary commands via sudo. Also, many
programs (such as editors) allow the user to run commands via shell
escapes, thus avoiding sudo's checks. However, on most systems it is
possible to prevent shell escapes with sudo's noexec functionality.
See the sudoers(5) manual for details.
The second: a glimpse into the Unix concept of the 'shell'.
It is not meaningful to run the cd command directly via sudo, e.g.,
$ sudo cd /usr/local/protected
since when the command exits the parent process (your shell) will still
be the same. Please see the EXAMPLES section for more information.
Ken Thompson and Dennis Ritchie were stuck there for two months when first building Unix. They'd use 'cd' to change directories but always ended up back where they started from. They ripped the system apart, debugged it intensely without success, until coins finally started dropping down the slots.
- Execution of any program on Unix invariably involves creating a new 'shell'. Think layers of an onion. Or better yet: hack a bit from Terminal.
$ sh
sh-3.2$ zsh
% tcsh
% csh
% bash
- You have to issue 'exit' commands to get back where you started from. (And unfortunately Apple engineers introduced yet another bug in 10.6 which makes this problematic. Don't hold your breath for a fix.)
- But the basic idea is you have 'shells' overlapping each other: your initial shell calls 'sh' in the example above and then waits to continue until the new shell exits. The second shell calls a shell and then waits to continue until that shell exits; and so on.
- Finally: each shell has its own set of 'environment variables'. Such as the 'current working directory'.
$ cd /bin
$ set | grep PWD
OLDPWD=/
PWD=/bin
$ set | grep ^PWD
PWD=/bin
$ echo $PWD
/bin
- So using cd to change directories was fine; the code Ken and Dennis had written was correct; but the directory only changed in the new shell; and immediately the command ran, the system went back to the old shell again, where the directory hadn't changed.
- Ken Thompson did a 'code fix' to make cd propagate the new 'PWD' back to the calling shell.
- The behaviour of sudo is thus much the same as the 'pre-fix' cd.
All sudo really does is run your command as its own - as root - provided you pass all the 'tests'. But this command runs of course in its own shell (which exits immediately afterward). Thus the caveat.
So try the dmesg command in CLIX. (That's where you ultimately want it anyway.)
Something like the above. Then run it and save it.
Set UID & Scripts
Your kernel build should outlaw them but the option's there for those who want it: allowing ordinary shell script files to be marked 'set UID' and run as root. This is of course foolhardy and works hand in hand with world-writable files: they're no-nos.
So it follows that running external scripts through Terminal or CLIX or any program is ripe with risks. If you absolutely have to run a script as root then you might consider the following introductory snippet.
if [[ `stat -f %u%g $0` != "080" ]] ; then
echo "Script ownership is `stat -f %u:%g $0` but should be 0:80."
exit
fi
if [[ `stat -f %p $0` != "100550" ]] ; then
echo "Script mode is `stat -f %p $0` but should be 100550."
exit
fi
The first test makes sure the file is owned by root:admin. The second test makes sure the file is not writable (or even readable by anyone outside the admin group). And the script exits gracefully in either case.
You can also ask CLIX to prompt you any time sudo is invoked.
defaults write com.rixstep.CLIX SudoAlert 1
This is what happens next you use sudo within CLIX.
Click the default 'Allow Once' and the current invocation goes through; click 'Deny' and that's the end of that; click 'Allow All' and all invocations (for the current command only) are allowed. (The next sudo command will get you the same prompt again.)
But as pointed out in the CLIX documentation, this is not a complete or foolproof system.
[Note this isn't foolproof: a malfeasant sufficiently acquainted with your computing habits can delete the preferences file. Safest of all is to manually check external scripts before running or better yet to not run external scripts at all.]
Run the following command to find out if your kernel build allows set ID scripts.
$ sysctl kern.sugid_scripts
kern.sugid_scripts: 0
Better yet: filter out everything but the reply ('0' for 'no', '1' for 'yes').
$ sysctl kern.sugid_scripts | sed s/'kern.sugid_scripts: '//
0
Hopefully your system will have the same answer.
You turn CLIX sudo alerts off by reversing the original command.
defaults write com.rixstep.CLIX SudoAlert 1
Or better yet: by removing the key altogether.
defaults delete com.rixstep.CLIX SudoAlert
/bin
Time to venture out on your own. Navigate with Terminal to /bin and try to open a manpage for each file. See what you can find. You get a head start.
$ df
Filesystem 512-blocks Used Available Capacity Mounted on
devfs 218 218 0 100% /dev
map -hosts 0 0 0 100% /net
map auto_home 0 0 0 100% /home
$ man df
DF(1) BSD General Commands Manual DF(1)
NAME
df -- display free disk space
SYNOPSIS
df [-b | -h | -H | -k | -m | -g | -P] [-ailn] [-t] [-T type]
[file | filesystem ...]
LEGACY SYNOPSIS
df [-b | -h | -H | -k | -m | -P] [-ailn] [-t type] [-T type] [file |
filesystem ...]
DESCRIPTION
The df utility displays statistics about the amount of free disk space on
the specified filesystem or on the filesystem of which file is a part.
Values are displayed in 512-byte per block counts. If neither a file or
a filesystem operand is specified, statistics for all mounted filesystems
are displayed (subject to the -t option below).
The following options are available:
-a Show all mount points, including those that were mounted with the
MNT_IGNORE flag.
-b Use (the default) 512-byte blocks. This is only useful as a way
to override an BLOCKSIZE specification from the environment.
-g Use 1073741824-byte (1-Gbyte) blocks rather than the default.
Note that this overrides the BLOCKSIZE specification from the
environment.
-H "Human-readable" output. Use unit suffixes: Byte, Kilobyte,
Megabyte, Gigabyte, Terabyte and Petabyte in order to reduce the
number of digits to three or less using base 10 for sizes.
-h "Human-readable" output. Use unit suffixes: Byte, Kilobyte,
Megabyte, Gigabyte, Terabyte and Petabyte in order to reduce the
number of digits to three or less using base 2 for sizes.
-i Include statistics on the number of free inodes.
-k Use 1024-byte (1-Kbyte) blocks, rather than the default. Note
that this overrides the BLOCKSIZE specification from the environ-
ment.
-l Only display information about locally-mounted filesystems.
-m Use 1048576-byte (1-Mbyte) blocks rather than the default. Note
that this overrides the BLOCKSIZE specification from the environ-
ment.
-n Print out the previously obtained statistics from the filesys-
tems. This option should be used if it is possible that one or
more filesystems are in a state such that they will not be able
to provide statistics without a long delay. When this option is
specified, df will not request new statistics from the filesys-
tems, but will respond with the possibly stale statistics that
were previously obtained.
-P Use (the default) 512-byte blocks. This is only useful as a way
to override an BLOCKSIZE specification from the environment.
-T Only print out statistics for filesystems of the specified types.
More than one type may be specified in a comma separated list.
The list of filesystem types can be prefixed with ``no'' to spec-
ify the filesystem types for which action should not be taken.
For example, the df command:
df -T nonfs,mfs
lists all filesystems except those of type NFS and MFS. The
lsvfs(1) command can be used to find out the types of filesystems
that are available on the system.
-t If used with no arguments, this option is a no-op (Mac OS X
already prints the total allocated-space figures). If used with
an argument, it acts like -T, but this usage is deprecated and
should not be relied upon.
ENVIRONMENT
BLOCKSIZE If the environment variable BLOCKSIZE is set, the block counts
will be displayed in units of that size block.
BUGS
The -n and -t flags are ignored if a file or filesystem is specified.
LEGACY DESCRIPTION
The "capacity" percentage is normally rounded up to the next higher inte-
ger. In legacy mode, it is rounded down to the next lower integer.
When the -P option and the -k option are used together, sizes are
reported in 1024-blocks. In legacy mode, when the -P option and -k
option are used together, the last option specified dictates the reported
block size.
The -t option is normally a no-op (Mac OS X already prints the total
allocated-space figures). In legacy mode, it is equivalent to -T.
For more information about legacy mode, see compat(5).
SEE ALSO
lsvfs(1), quota(1), fstatfs(2), getfsstat(2), statfs(2), getmntinfo(3),
compat(5), fstab(5), mount(8), quot(8)
HISTORY
A df command appeared in Version 1 AT&T UNIX.
BSD May 8, 1995 BSD
A hint: always look for an option without command line switches. And don't run any command with sudo until you've studied the documentation and are sure you know what you're doing. Read carefully and happy hacking.
See Also Rixstep FTP: CLIX Download CLIX: Don't Sell a Man a Fish
|