On Fri, 21 Oct 2011 18:53:33 +0200 "Christopher J. Ruwe" <c...@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
signature.asc
Description: PGP signature