trying to learn systems programming, fear I have not understood
and thus messed up
Christopher J. Ruwe
cjr at cruwe.de
Sat Oct 22 14:05:13 UTC 2011
On Fri, 21 Oct 2011 18:53:33 +0200
"Christopher J. Ruwe" <cjr at cruwe.de> wrote:
> [...]
>
> 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.
It seems I have indeed not understood GETPWNAM correctly. I have worked
out a method which works by calling GETPWNAM twice:
else {
/*
* operation as follows:
* a_name->val is passed as usermod <uname>
* arg->val is passed as -u <uname>
*
* first check if we do someting stupid, i.e., want
* to set root uid to some other users uid or
* to set some user accout's uid to root uid.
* then get pwd to that of uname passed as -u <uname>.
* store uid from that pwdent.
* get pwd to that of uname passed as usermod <uname>
* change uid of that latter uid to the one stored
*/
if(strcmp(a_name->val,"root") == 0)
errx(EX_DATAERR, "can't change uid of `root' account");
if(strcmp(arg->val, "root") == 0)
warnx("WARNING: account `%s' will have a uid of 0 (superuser
access!)", pwd->pw_name);
if(!(pwd = GETPWNAM(arg->val))) /* -u <uname>*/
errx(EX_DATAERR, "User %s does not exist", arg->val);
int alias_uid = pwd->pw_uid;
if(!(pwd = GETPWNAM(a_name->val))) /*usermod <uname>*/
errx(EX_DATAERR, "User %s does not exist", a_name->val);
pwd->pw_uid = (uid_t) alias_uid;
warnx("User %s's uid changed to %d", pwd->pw_name, pwd->pw_uid);
edited = 1;
}
As I stil do not know why the latter variant of my code worked and the
former does not, I would still appreciate any comment or explanation which would help me understanding GETPWNAM and getpwnam.
Thanks and cheers,
--
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/20111022/72463e53/signature.pgp
More information about the freebsd-questions
mailing list