[comp.unix.wizards] opening accounts from a non-root account ..

lubkt@spectrum.CC.Lehigh.EDU (Binod K. Taterway) (06/13/91)

I want an administrative staff to open Sun accounts for me. She will
have to change passwords, change shells, change quotas, and other
account-related items.  I have created an account for her, call it
'admin.'  The admin user belongs to the group 'admin.' All yp related
stuff are modifiable by this user. I have created /etc/passwd file
with write permission to admin.

When I (as root) create accounts, I never work on the actual password
file; instead, I work on its copy using the -F option of passwd(1).
Then I check its contents using cops and other locally written
packages for any error, then copy it to the proper location in /var/yp
and run a make to update the NIS password map.

All of this works fine for root; but -F option of passwd(1) does not
work with non-root. So, I thought I might get around by generating
encrypted password in the first place.

Here begins my journey to the wonderous land of crypt(3), login(1),
DES, and a host of other programs. I realize crypt cannot generate
initial encrypted password because it doesn't have the right seed. Let
EPW be the encrypted password of the clear-text password, PW. Then,

	EPW = crypt(PW, EPW)

The second parameter of crypt is the seed: if the seed is same as EPW,
then the result of crypt is same EPW. This is what is presumably used
by login programs to validate a user.

But, my problem is to generate EPW without initial seed.

So I thought, may be, I will create a dummy user, and get the EPW by
using the passwd(1) program directly (change password of this dummy
user, awk/grep the password field of this user, and use it in the EPW
field of the new user's password. But this means that I will working
on the password file directly, and I don't like to do that.

Perhaps there is simpler way. Sure, use setuid shell script. Being a
security advocate, I just don't write such scripts and I am not going
to start now. But I am dying to relieve myself of the burden of
day-to-day account management. Perhaps someone would like to share
her/his recipe on this issue if they have found a way of doing this
neatly from a non-root account.

--

---
Binod Taterway                     |    lubkt@spectrum.CC.Lehigh.EDU
Sr. User Consultant                |    bt00@lehigh.BITNET
Lehigh University Computing Center |    (215) 758-3984 (off)
Bethlehem, PA 18015                |    (215) 758-4983 (fax)

hp@vmars.tuwien.ac.at (Peter Holzer) (06/13/91)

lubkt@spectrum.CC.Lehigh.EDU (Binod K. Taterway) writes:


>All of this works fine for root; but -F option of passwd(1) does not
>work with non-root. So, I thought I might get around by generating
>encrypted password in the first place.

Good idea.

>Here begins my journey to the wonderous land of crypt(3), login(1),
>DES, and a host of other programs. I realize crypt cannot generate
>initial encrypted password because it doesn't have the right seed. Let
>EPW be the encrypted password of the clear-text password, PW. Then,

>	EPW = crypt(PW, EPW)

>The second parameter of crypt is the seed: if the seed is same as EPW,
>then the result of crypt is same EPW. This is what is presumably used
>by login programs to validate a user.

>But, my problem is to generate EPW without initial seed.

The manual [crypt(3), makekey(8)] states that the salt are two
characters from the set [A-Za-z0-9./]. The salt is stored together with
the password so we can just use some random salt:

[...]
char saltchars [] = "AB...YZab...yz0123456789./";
char salt[2];

srand ((int)(time ((time_t *)0) + getpid()));
salt[0] = saltchars[rand() % 64];
salt[1] = saltchars[rand() % 64];
epw = crypt(pw, salt);
[...]

--
|    _  | Peter J. Holzer                       | Think of it   |
| |_|_) | Technical University Vienna           | as evolution  |
| | |   | Dept. for Real-Time Systems           | in action!    |
| __/   | hp@vmars.tuwien.ac.at                 |     Tony Rand |

quillen@orion.fccc.edu (John Quillen) (06/14/91)

>lubkt@spectrum.CC.Lehigh.EDU (Binod K. Taterway) writes...
>
>DES, and a host of other programs. I realize crypt cannot generate
>initial encrypted password because it doesn't have the right seed. Let
>EPW be the encrypted password of the clear-text password, PW. Then,
>
>		EPW = crypt(PW, EPW)

Crypt can, in fact, generate the right password.  The "seed" is better known as
the salt (man 3 crypt for an explanation).  The salt appears as the first two
characters of the encrypted string.  That is how multiple users can have the
same password and unique encrypted passwords.

Here's a code fragment you may find useful...

John

#include <stdio.h>

/* call once before making getrand calls */
#define seedrand()			srand( (int) time( 0 ) + getpid() )

/* generate random number in given range */
#define getrand( lo, hi )	(( rand() % ( hi - lo )) + lo )

/*
 * mk_pass - generate encrypted string passwd
 */
char *
mk_pass( pass )
char *pass;		/* unencrypted passwd */
{
	extern char *crypt();
	char salt[ 3 ];

	salt[ 0 ] = (char) getrand( 'a', 'z' );
	salt[ 1 ] = (char) getrand( 'A', 'Z' );
	salt[ 2 ] = (char) NULL;

	return( crypt( pass, salt ));
}

-- 
--------------------------------------------------------------------------
John W. Quillen, Jr.                         Phone: (215) 728-3660
Research Computing Services                  FAX:   (215) 728-3574
The Fox Chase Cancer Center                  internet: JW_Quillen@fccc.edu
7701 Burholme Avenue            /-----------------------------------------
Philadelphia, PA  19111        /  "No matter where you go, there you are."
USA                           /                 - B. Banzai
--------------------------------------------------------------------------

chris@ec.uwa.oz.au (Christoph Uloth) (06/16/91)

quillen@orion.fccc.edu (John Quillen) writes:

>mk_pass( pass )
>char *pass;		/* unencrypted passwd */
>{
>	extern char *crypt();
>	char salt[ 3 ];

>	salt[ 0 ] = (char) getrand( 'a', 'z' );
>	salt[ 1 ] = (char) getrand( 'A', 'Z' );
>	salt[ 2 ] = (char) NULL;

>	return( crypt( pass, salt ));
>}

the line seedrand(); is missing after char salt[ 3 ];