203 lines
10 KiB
HTML
203 lines
10 KiB
HTML
<!--startcut ==============================================-->
|
|
<!-- *** BEGIN HTML header *** -->
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
|
<HTML><HEAD>
|
|
<title>Perl One-Liner of the Month: The Case of the Duplicate UIDs LG #85</title>
|
|
</HEAD>
|
|
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
|
|
ALINK="#FF0000">
|
|
<!-- *** END HTML header *** -->
|
|
|
|
<!-- *** BEGIN navbar *** -->
|
|
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="nielsen.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue85/okopnik.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../lg_faq.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="foolish.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
|
|
<!-- *** END navbar *** -->
|
|
|
|
<!--endcut ============================================================-->
|
|
|
|
<TABLE BORDER><TR><TD WIDTH="200">
|
|
<A HREF="http://www.linuxgazette.com/">
|
|
<IMG ALT="LINUX GAZETTE" SRC="../gx/2002/lglogo_200x41.png"
|
|
WIDTH="200" HEIGHT="41" border="0"></A>
|
|
<BR CLEAR="all">
|
|
<SMALL>...<I>making Linux just a little more fun!</I></SMALL>
|
|
</TD><TD WIDTH="380">
|
|
|
|
|
|
<CENTER>
|
|
<BIG><BIG><STRONG><FONT COLOR="maroon">Perl One-Liner of the Month: The Case of the Duplicate UIDs</FONT></STRONG></BIG></BIG>
|
|
<BR>
|
|
<STRONG>By <A HREF="../authors/okopnik.html">Ben Okopnik</A></STRONG>
|
|
</CENTER>
|
|
|
|
</TD></TR>
|
|
</TABLE>
|
|
<P>
|
|
|
|
<!-- END header -->
|
|
|
|
<H3>Chapter 1</H3>
|
|
|
|
<p>The e-mail was short, succinct, and got right to the point.
|
|
<BLOCKQUOTE><PRE>
|
|
Woomert -
|
|
I'll be short, succinct, and get right to the point.
|
|
Three-company merger.
|
|
Nervous sysadmin.
|
|
3000+ users.
|
|
/etc/passwd.
|
|
UIDs.
|
|
Regards,
|
|
Frink Ooblick
|
|
</PRE></BLOCKQUOTE>
|
|
<p>Woomert Foonly, the Hard-Nosed Computer Detective, chuckled to himself.
|
|
The client had been rather loud and incoherent on the phone, with "It doesn't
|
|
work!" and "I need help!" being the chief features of his conversation.
|
|
Woomert had sent Frink to the site to reconnoiter, and the above was the
|
|
highly satisfactory result. All that remained was to come up with the solution;
|
|
given that only a few short hours remained before the client shut down
|
|
for the day, Woomert decided to use his time productively. Let's see -
|
|
where was his favorite pillow?...
|
|
|
|
<H3>Chapter 2</H3>
|
|
|
|
<p>Refreshed and ready, Woomert appeared at the site, and immediately encountered
|
|
a rather excited Frink.
|
|
<p> - "Woomert, it's terrible! The file is far too long to search
|
|
manually, and the UIDs are all over the map. The sysadmin is contrite,
|
|
frantic, and panicked by turns, and his hair is almost all gone. What can
|
|
we do?"
|
|
<p> - "No worries, mate... oh, sorry. I was just in Canberra a few
|
|
hours ago, and some of the influence is still with me. I can tell you from
|
|
horrible experience that tomorrow will be even worse: I've got to be in
|
|
Dallas in the morning, New York in the afternoon, and Tel Aviv in the evening.
|
|
I would advise you to wear earplugs, or absent yourself from my environs
|
|
until the accents fade. Ah, the perils of travel..."
|
|
<p>Frink was becoming visibly upset.
|
|
<p> - "Woomert - you're not taking this seriously. Can't you see that
|
|
this is a major problem?"
|
|
<p> - "Oh, this? Relax, take it easy. It's not nearly as bad as it
|
|
looks, Frink; in fact..."
|
|
<p>Woomert deftly extracted his favorite typing gloves from his pocket
|
|
and slipped them on.
|
|
<p> - "...Perl makes it rather trivial. What we'll do is give the
|
|
sysadmin a couple of command-line tools that he can use to resolve this
|
|
problem, and - since he's using 'bash' - he'll be able to pull them up
|
|
with the 'up-arrow' key as he needs them. Here we go!"
|
|
<pre>
|
|
<hr width="100%">perl -F: -walne'$h{$F[2]}.="$F[0] ";END{$h{$_}=~/ ./&&print"$_: $h{$_}"for keys%h}' /etc/passwd
|
|
<hr
|
|
width="100%"></pre>
|
|
A list of duplicate UIDs, along with their related usernames scrolled down
|
|
the screen after Woomert pressed the "Enter" key. Both Woomert and
|
|
Frink noted with interest that there was a <b>triple</b> entry for UID0
|
|
-
|
|
<p><tt>0: root sashroot kill3r</tt>
|
|
<p> - "Well, well. Looks like somebody managed to break in and give
|
|
themselves a UID0 (root) account. 'sashroot' is OK - that's the 'standalone
|
|
shell' for those rough repair jobs - but 'kill3r'? Well, we'll let
|
|
the client know; meanwhile, on with the current problem. The sysadmin will
|
|
now have a list of all the duplicates - there don't seem to be all that
|
|
many - but searching for the next available UID could be a pain. So,
|
|
here's a second tool -"
|
|
<pre>
|
|
<hr width="100%">perl -wle'{getpwuid++$n&&redo;print$n}'
|
|
<hr
|
|
width="100%"></pre>
|
|
- "That should give him a good start on getting it all straightened
|
|
out. As for us - we're homeward bound!"
|
|
|
|
<H3>Chapter 3</H3>
|
|
|
|
<p>When they had returned to Woomert's house and were seated in front of
|
|
the fireplace - the night had been a cold one, and the wind whistled outside
|
|
the window - Frink looked expectantly at Woomert. Noting the look, Woomert
|
|
laughed.
|
|
<p> - "I know, I know. I should explain, shouldn't I? The air of mystery
|
|
is a sharp, pleasant thing, but it is as nothing compared to the pleasure
|
|
of learning. Here, let's start with the first one:
|
|
<pre>
|
|
<hr width="100%">perl -F: -walne'$h{$F[2]}.="$F[0] ";END{$h{$_}=~/ ./&&print"$_: $h{$_}"for keys%h}' /etc/passwd
|
|
<hr
|
|
width="100%"></pre>
|
|
"First, take a look at the command-line switches I used:"
|
|
|
|
<PRE>
|
|
-w Enable warnings
|
|
-a Autosplit (see "-F")
|
|
-l Enable line-end processing
|
|
-n Implicit non-printing loop
|
|
-e Execute the following commands
|
|
-F: Use ':' as the separator for the '-a' autosplit
|
|
</pre>
|
|
"If you remember our <a href="../issue84/okopnik.html">last
|
|
adventure</a>, all of the above except '-a' and '-F' are already familiar
|
|
to you. Autosplitting splits the lines read in by '-n' or '-p', using whitespace
|
|
as a default separator and saving the result in the '@F' array. '-F' optionally
|
|
redefines the separator by which to split."
|
|
<p>"Since we're reading in '/etc/passwd', let's look at the format of the
|
|
individual lines in it:"
|
|
<pre>borg:x:1026:127:All your base are belong to us!:/home/borg:/bin/bash</pre>
|
|
"There are seven standard fields, laid out as 'name - passwd - UID - GID
|
|
- GECOS - dir - shell'. The only things we're interested in for the moment
|
|
are name and UID; what I'm going to do is build a hash - a very important
|
|
data structure in Perl, one of the three basic ones - that contains the
|
|
UID (3rd field) as the <b>key</b>, and the name (1st field), followed
|
|
by a space, as the <b>value</b>, for all the entries in '/etc/passwd':
|
|
<pre>$h{$F[2]}.="$F[0] "</pre>
|
|
Since usernames can't have spaces in them, it makes a convenient separator.
|
|
Once that's done, I'll loop over the hash and print out any value which
|
|
contains a space followed by any character:"
|
|
<br>
|
|
<pre>$h{$_}=~/ ./&&print"$_: $h{$_}"for keys%h}</pre>
|
|
"I see you still look puzzled. Here, let me write out the above in a more
|
|
readable form:"
|
|
<p><tt>for ( keys %h ){
|
|
# Loop over the "%h" hash</tt>
|
|
<br><tt> if ( $h{$_} =~ / ./ ){
|
|
# Does the value contain a space followed by anything?</tt>
|
|
<br><tt> print "$_: $h{$_}\n";
|
|
# If so, print the UID, a colon, a space, and the value</tt>
|
|
<br><tt> }</tt>
|
|
<br><tt>}</tt>
|
|
<p>"If you think about it, you'll see that the only thing that will match
|
|
the above regex is a value with more than one name in it - meaning a duplicate
|
|
UID."
|
|
<p> - "All right - now I can see how you got the results. What
|
|
about the second expression, the 'next available UID' tool?"
|
|
<p> - "Ah, you mean this one:"
|
|
<p>
|
|
<hr width="100%"><tt>perl -wle'{getpwuid++$n&&redo;print$n}'</tt>
|
|
<br>
|
|
<hr
|
|
width="100%">
|
|
<p>"It's nothing but a short loop in which I check if the UID specified
|
|
by '$n' exists. If that test succeeds - meaning that there <b>is</b> a
|
|
UID equal to '$n' in use - 'redo' gets invoked, '$n' is incremented, and
|
|
the test happens again. If it fails, however, '$n' is printed to STDOUT
|
|
and the program exits. Useful, and not too complicated. Just a bit of work,
|
|
and they should have it all done. The security breach is something else,
|
|
but at least now they know about it..."
|
|
|
|
|
|
|
|
|
|
|
|
<!-- *** BEGIN copyright *** -->
|
|
<hr>
|
|
<CENTER><SMALL><STRONG>
|
|
Copyright © 2002, Ben Okopnik.
|
|
Copying license <A HREF="../copying.html">http://www.linuxgazette.com/copying.html</A><BR>
|
|
Published in Issue 85 of <i>Linux Gazette</i>, December 2002
|
|
</STRONG></SMALL></CENTER>
|
|
<!-- *** END copyright *** -->
|
|
<HR>
|
|
|
|
<!--startcut ==========================================================-->
|
|
<CENTER>
|
|
<!-- *** BEGIN navbar *** -->
|
|
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="nielsen.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue85/okopnik.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../lg_faq.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="foolish.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
|
|
<!-- *** END navbar *** -->
|
|
</CENTER>
|
|
</BODY></HTML>
|
|
<!--endcut ============================================================-->
|