Interview question: Recreate groups PART 2

In a previous post you might have noticed that I wrote some code that was incomplete. (Thanks Dave for pointing that out! Greatly Appreciated!) And now that some time has passed, and my life has calmed down enough to give this another shot, here is my new version of the code.

You might notice that a lot has changed since the last version. Most importantly, I got rid of going the a shell out, as it has been taught to me that there are security concerns with doing so. You should also notice that I'm using regex's to do the filtering, I'm sure these could be tightened down a little bit. But I won't get better with them unless I at least start using them. I'm also getting the default group id of the user, and returning that first in the output. And finally, I am doing some error checking to make sure that the account is actually in the system; something my previous script did not check for.

All in all, I'm happier with this script than the first version. And of course, I'm interested in seeing if anyone can find out other bugs that exist inside the code.

  1. #!/usr/bin/perl
  2. #######################################################################
  3. # Created By: Bryce Verdier
  4. # on 1/19/10
  5. # modified to fix errors 3/12/2010
  6. # Function: rework the output of the unix groups command
  7. # NOTE: FOR USE ON UNIX MACHINES!
  8. #######################################################################
  9.  
  10. use warnings;
  11. use strict;
  12. use Getopt::Std;
  13.  
  14. sub get_gid
  15. {
  16. my ($name) = @_;
  17.  
  18. return getgrnam($name);
  19. }
  20.  
  21. sub open_and_parse
  22. {
  23. my ($in_user, $in_gid) = @_;
  24. my $guid_name;
  25. my @split;
  26. my @parse_groups;
  27. my @end_array;
  28.  
  29.  
  30. open(PASSWD, "/etc/group");
  31. while(<PASSWD>){
  32.  
  33. # This line is to grab the default in_gid name
  34. if ( $_ =~ m/^.*\:$in_gid\:\:*/ ){
  35. @split = split(':', $_);
  36. $guid_name = $split[0];
  37. }
  38.  
  39. # This line is to grab any line which has the in_user in it
  40. # while also rejecting the line with the in_gid number in it
  41. elsif ( $_ =~ m/^.*$in_user.*/ ){
  42. @split = split(':', $_);
  43. next if ( $split[2] == $in_gid );
  44. push (@parse_groups, $split[0]);
  45. }
  46.  
  47. # we don't care about anything else so skip it
  48. else{
  49. next;
  50. }
  51. }
  52.  
  53. push ( @end_array, $guid_name);
  54. push ( @end_array, @parse_groups);
  55.  
  56. return @end_array;
  57. }
  58.  
  59.  
  60. ## Main script starts here
  61. our($opt_u);
  62. getopts('u:');
  63.  
  64. my $gid = get_gid($opt_u);
  65.  
  66. if ( defined($gid) ) {
  67. my @groups = open_and_parse($opt_u, $gid);
  68. print "$opt_u : @groups\n";
  69. }else{
  70. print "$0: $opt_u: No such user\n";
  71. }
  72.  
  73. exit 0;

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <geshi>, <c>, <cpp>, <drupal5>, <drupal6>, <haskell>, <java>, <javascript>, <perl>, <php>, <python>, <ruby>. The supported tag styles are: <foo>, [foo].

More information about formatting options

If you made it this far down into the article, hopefully you liked it enough to share it with your friends. Thanks if you do, I appreciate it.

Bookmark and Share