trying to learn systems programming, fear I have not understood and thus messed up

Christopher J. Ruwe cjr at cruwe.de
Fri Oct 21 16:53:47 UTC 2011


To improve on my C and to learn something about systems programming, I
have begun to pick out "bite-size bits" from the bin-PRs. Currently, I
am dispairing about bin/149972, which is about 1) adding error handling
to pw being invoced "pw -u <username>" and 2) trying to get a uid from
the (incorrectly) passed username. Currently, I cannot accomplish want
I wanted to do, so I turn here for hints or help.

Three developers which I have failed to reach by mail (gpf@, kibab@,
bcr@) have added the necessary code


if ((arg = getarg(args, 'u')) != NULL) {
   if(isdigit((unsigned char)*arg->val)) {
   pwd->pw_uid = (uid_t) atol(arg->val);
   edited = 1;
   if (pwd->pw_uid != 0 && strcmp(pwd->pw_name, "root") == 0)
      errx(EX_DATAERR, "can't change uid of `root' account");
   if (pwd->pw_uid == 0 && strcmp(pwd->pw_name, "root") != 0)
      warnx("WARNING: account `%s' will have a uid of 0 (superuser
access!)", pwd->pw_name); } else {
  /* Found something, but not a number */
  /*
   * XXX Shouldn't we try to map the passed string to the username?
   * man page however says that we're expecting numeric uid...
   */
  errx(EX_DATAERR, "Expected numeric user id as an argument to -u\n");
  }
}

I have tried to follow the suggestion from the comment by modifiying
the else-statement thus:

} else {
  struct passwd *trgpwd;
  if (!(trgpwd = GETPWNAM(arg->val)))
     errx(EX_DATAERR, "User %s does not exist", arg->val);
   
   if (strcmp(a_name->val,"root") == 0)
      errx(EX_DATAERR, "can't change uid of `root' account");
   if (strcmp(trgpwd->pw_name, "root") == 0)
      warnx("WARNING: account `%s' will have a uid of 0 (superuser
access!)", pwd->pw_name);

   pwd->pw_uid = (uid_t) (trgpwd->pw_uid);		    
   edited = 1;
} 

What happens is not what I intended. I invoke as "sudo ./pw usermod
testuser1 -u testuser2". I can get testuser2's pwd-entry by GETPWNAM
allright, but when I assign the pw_uid, so as to make testuser2's uid
the same as testuser1's and imgaining to retain all other values, ./pw
reports "pw: user 'testuser2' disappeared during update" and the
testuser2's /etc/passwd entry is replaced by testuser1's.

I fear I have not understood GETPWNAM correctly, as it seems to replace
the struct pwd as some sort of sideeffect. I could manually set all
pwd-members to the correct ones (those of testuser2), but I fear that I
have messed something up beforehand.

I am grateful for any suggestions and/or correction. 
-- 
Christopher J. Ruwe
TZ GMT + 2

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 834 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-questions/attachments/20111021/21c2ff14/signature.pgp


More information about the freebsd-questions mailing list