OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
newuser question

From: Keith Richardson (keith.alangmail.com)
Date: Tue Feb 07 2006 - 06:36:20 CST


Hello,

pkg_create(1) says I can force a UID by prefixing the desired UID with '!'.
That implies that, if the UID is *not* prefixed with '!', the install process
will *not* force the UID supplied but, rather, give you some other available
UID. Really going out on a limb, I would think that the next available UID
would be used.

However, testing a newuser command both with and without the '!' prefix
shows that if the UID (but not user name) already exists, useradd will still
be called with the already-in-use UID. Of course, this fails.

Not specifing the UID still gives me a dynamic one but within the range of
usermgmt.conf(5). This range isn't suitable for daemon users though, from
a "standards" standpoint.

What did I miss? I love Google but sometimes when I say "newuser", I don't
mean "new user"...*

*Also, even though only ~53 ports use newuser, coordination
(a.k.a. small headache) still needs to happen to ensure no two ports ask
for the same UID. Are there any reasons *not* to provide the next-availble
UID if the '!' prefix wasn't specified? I am not familiar with all the code
but the attached **untested** patch should do the trick. It's probably not
in the best function design-wise but you get the idea.
**
Thanks,
Keith
*

newuser* /name/:/uid/:/group/:/loginclass/:/comment/:/home/:/shell/
             During pkg_add(1) <http://www.openbsd.org/cgi-bin/man.cgi?query=pkg_add&sektion=1&arch=i386&apropos=0&manpath=OpenBSD+Current>, create a new user. Happens before any file
             creation. All fields correspond to useradd(8) <http://www.openbsd.org/cgi-bin/man.cgi?query=useradd&sektion=8&arch=i386&apropos=0&manpath=OpenBSD+Current> parameters. Some
             fields are optional and can be left empty. If the user already
             exists, no action is taken. Individual fields can be prefixed by
             a `!' to make sure an existing user matches. For instance, the
             directive newuser foo:!42 will make sure user foo has UID 42.
             During pkg_delete(1) <http://www.openbsd.org/cgi-bin/man.cgi?query=pkg_delete&sektion=1&arch=i386&apropos=0&manpath=OpenBSD+Current>, users will be deleted if extra clean-up has
             been requested, and if other installed packages don't list the
             same user.

*** PackingElement.pm.dist Tue Feb 7 05:33:26 2006
--- PackingElement.pm Tue Feb 7 05:58:36 2006
***************
*** 814,837 ****
--- 814,842 ----
  package OpenBSD::PackingElement::NewUser;
  our ISA=qw(OpenBSD::PackingElement::Action);
  __PACKAGE__->setKeyword("newuser");
  
  sub category() { "users" }
  sub keyword() { "newuser" }
  
  sub new
  {
          my ($class, $args) = _;
          my ($name, $uid, $group, $loginclass, $comment, $home, $shell) =
              split /\:/, $args;
+
+ if ($uid !~ m/^!/ ) {
+ $uid++ while ( defined getpwuid($uid));
+ }
+
          bless { name => $name, uid => $uid, group => $group,
              class => $loginclass,
              comment => $comment, home => $home, shell => $shell }, $class;
  }
  
  sub check
  {
          my $self = shift;
          my ($name, $passwd, $uid, $gid, $quota, $class, $gcos, $dir, $shell,
              $expire) = getpwnam($self->{name});
          return undef unless defined $name;
          if ($self->{uid} =~ m/^\!/) {
***************
*** 871,894 ****
--- 876,904 ----
  package OpenBSD::PackingElement::NewGroup;
  our ISA=qw(OpenBSD::PackingElement::Action);
  
  __PACKAGE__->setKeyword("newgroup");
  
  sub category() { "groups" }
  sub keyword() { "newgroup" }
  
  sub new
  {
          my ($class, $args) = _;
          my ($name, $gid) = split /\:/, $args;
+
+ if ($gid !~ m/^!/ ) {
+ $gid++ while ( defined getgrgid($gid));
+ }
+
          bless { name => $name, gid => $gid }, $class;
  }
  
  sub check
  {
          my $self = shift;
          my ($name, $passwd, $gid, $members) = getgrnam($self->{name});
          return undef unless defined $name;
          if ($self->{gid} =~ m/^\!/) {
                  return 0 unless $gid == $';
          }
          return 1;