Summary:How to make an encrypt. Password

From: David Gempton (ttcdg@cyberspace.co.nz)
Date: Thu Apr 18 1996 - 01:30:32 CDT


Wow !

What a responce. I have attached the best of the replies that I recieved. A number of the replies contained source code which I have also attached.

Original Question:
================================================
> Could someone tell me how to generate the encrypted passwd suitable for
> going into the NIS+ passwd.org_dir table.
>
> I am putting together a adduser script and my users will have DES
> credentials, so I need to be able to taker a plain test password and
> generate the encrypted version.

Summary:
================================================
Write a C program to do it for you. But basically the encrypted passwords are generated with the crypt command in the following fashion:
Tim Boemker of Optimum Group suggested ...

"I don't use NIS+, but I'll speculate that it uses crypt(3), just like
/etc/passwd. You can check whether it does or not by testing an
encrypted password: if you know that a particular password is A in
plain text and B encrypted, try encrypting A using the first 2 chars of
B as the salt and see if the result is B."

And the most compact piece of code came from Jim McLean-Lipinski

pwcrypt.c
---------------------------------%<-----------------------------------
#include <stdio.h>
#include <pwd.h>
main ()
{
        char salt[2];
        char pw_crypt[9];
        fscanf(stdin, "%s%s", salt, pw_crypt);
        fprintf(stdout, "%s",crypt(pw_crypt, salt), 13 );
        exit(0);
}
---------------------------------%<-----------------------------------
Syntax: pwcrypt plain_text_passwd salt

Replies: & Code.
================================================

----------
X-Sun-Data-Type: text
X-Sun-Data-Description: text
X-Sun-Data-Name: text
X-Sun-Charset: us-ascii
X-Sun-Content-Lines: 12

Dave:

I have added the framework of our adduser script which should give
you the info you need.

--
******************************************************************************
* Russell Weeks                             rweeks@sunfs.math.usu.edu        *
* System Manager                            TEL: (801)797-4061               *
* Department of Mathematics & Statistics    FAX: (801)797-1822               *
* Utah State University                     WWW: http://xserver.math.usu.edu *
******************************************************************************
----------
X-Sun-Data-Type: shell-script
X-Sun-Data-Description: shell-script
X-Sun-Data-Name: adduser
X-Sun-Charset: us-ascii
X-Sun-Content-Lines: 230

#!/bin/sh # # Framework of interactive script to add NIS+ user accounts # # USAGE: adduser # #-------------------------------------------------------------------------------

# who to send e-mail information about new accounts to--customize for your site: administrator=support

# where the master dot files are located, and their names--change to reflect your site: defaults=/usr/local/master

# list of files to set up in users home directories--customize for your site: deffiles='.Xdefaults .cshrc .login .profile .envfile .tcshrc .xsession .openwin-init .openwin-menu .emacs'

# nis+ nomain name--put your nisdomain after the equal sign, without a trailing dot: nisdomain=

# fully qualified name (eg machine1@abc.com)--add after equal sign for your site: fullyqualified= #------------------------------------------------------------------------------- rearange() { last=$1; shift first=$* echo $first $last }

# ---- check to see if we have root access: if (test `whoami` != root) then echo "You must be root to create user accounts" exit 1 fi

# ---- make sure we're on the right host--again, customize for your site: case `/usr/ucb/hostname` in machine1) ;; machine2) /opt/local/bin/adduser; exit;; *) echo "You must be on machine1 to create nis+ accounts" echo "or machine2 to create local accounts." exit 1;; esac

ok=false # ---- get necessary information to create account: until (test $ok = true) do echo " " /usr/ucb/echo -n "Real Name: " ;read full_name /usr/ucb/echo -n "Username: " ;read user_name # ---- check for existing local entries, and abort if necessary: /usr/ucb/echo -n "checking local passwd file for $user_name..." grep "^${user_name}:" /etc/passwd > /tmp/pswd$$ n=`cat /tmp/pswd$$ |wc -l` if ( test $n -gt 0 ) then echo "found $n matching entries:" cat /tmp/pswd$$ echo aborting. exit else echo "no matches found" fi # ---- check for existing nis+ entries, and abort if necessary: /usr/ucb/echo -n "checking nis passwd file for $user_name..." niscat passwd.org_dir.$nisdomain. |grep "^${user_name}:" > /tmp/pswd$$ n=`cat /tmp/pswd$$ |wc -l` if ( test $n -gt 0 ) then echo "found $n matching entries:" cat /tmp/pswd$$ echo aborting. exit else echo "no matches found" fi rm /tmp/pswd$$

# ---- get the next uid in the sequence last=`niscat passwd.org_dir.$nisdomain. |sort -t: -rn +2 |tail +4 |head -1` lastuid=`echo $last |cut -d: -f3` uid=`echo $lastuid+1 |bc`

# -- get group info for new account--customize for your site: echo " " echo "Group Examples:" echo " 100) staff" echo " 110) guest" echo " 120) stat" echo " " /usr/ucb/echo -n "enter group: " ;read gid case $gid in 0|root) gid=0 group="root";; 100|staff) gid=100 group="staff";; 110|guest) gid=110 group="guest";; 12|daemon) gid=12 group="daemon";; 120|stat) gid=120 group="stat";; 60001|nobody) gid=60001 group="nobody";; 60002|noaccess) gid=60002 group="noaccess";; *) gid=$gid group="unknown";; esac echo group is $group gid is $gid

# -- read location for home directory, and make sure it exists--customize for your site: dok=false case $group in staff) default="/disk1/staff";; guest) default="/disk2/guest";; stat) default="/disk1/stat";; *) default="";; esac until (test $dok = true) do echo " " echo "Directory Examples:" echo " guests: /disk2/guest" echo " misc-accounts: /disk2/misc" echo " " /usr/ucb/echo -n "Home Directory Location ($default): " ;read home_dir if (test x$home_dir = x) then home_dir=$default fi if (test -d $home_dir ) then dok=true else echo "no such directory: $home_dir" fi done home_dir="$home_dir/$user_name"

# -- set default shell for new user: shell=/bin/csh

# -- verify all information before proceeding: echo " " echo "You entered the following:" echo " NAME: $full_name" echo " USERNAME: $user_name" echo " UID: $uid" echo " GROUP: $group ($gid)" echo " HOMEDIR: $home_dir" echo " " /usr/ucb/echo -n "Is this ok? (y/n): " ;read ans if ( test $ans = y ) then ok=true fi done

# ---- get and encrypt the password echo "You must enter an initial password for $user_name" ok=false until (test $ok = true) do echo " " /usr/ucb/echo -n "password: "; stty -echo; read pass1; stty echo; echo " " /usr/ucb/echo -n "verify: "; stty -echo; read pass2; stty echo; echo " " if (test ${pass1:-x} != ${pass2:-y}) then echo The two passwords you enterred were different. Please try again. else passwd=`/usr/local/bin/encrypt $pass1` ok=true fi done

# --- set the shadow fields expire=9100::::::

# ---- call the OS routines to create the NIS+ passwd table entry /usr/ucb/echo -n creating nis+ passwd entry... nistbladm -a -s : -t passwd_tbl name=$user_name passwd=$passwd uid=$uid gid=$gid gcos="$full_name" home=$home_dir shell=$shell shadow=$expire passwd.org_dir.$nisdomain. echo done

# ---- create an empty mail file for user in /var/mail touch /var/mail/$user_name chown $user_name /var/mail/$user_name chgrp mail /var/mail/$user_name

/usr/ucb/echo -n creating nis+ mail_alias entry... nistbladm -a -s : -t mail_aliases alias=$user_name expansion=$user_name@$fullyqualified comments="$full_name" mail_aliases.org_dir.$nisdomain. echo done

# ---- call the OS routines to create the NIS+ credentials /usr/ucb/echo -n creating nis+ credentials... nisaddcred -p $uid -P $user_name.$nisdomain. local echo done nisaddcred -p unix.$uid@$nisdomain -P $user_name.$nisdomain. -l $pass1 des

echo "account for $full_name has been created."

# ---- create account, copy default files, and set ownership/permissions: /usr/ucb/echo -n "creating home directory..." mkdir $home_dir chmod 755 $home_dir echo "$home_dir created" /usr/ucb/echo -n "copying default files..." for file in $deffiles do /usr/ucb/echo -n " $file" cp $defaults/$file $home_dir done chown -R $user_name $home_dir chgrp -R $gid $home_dir echo " done"

# ---- add an alias for new user to the aliases file, and rebuild them: echo "${user_name}:${user_name}@$fullyqualified" >> /etc/mail/aliases /usr/ucb/echo -n "updating aliases..." sleep 1 newaliases

# ---- mail info on new account to $administrator: /usr/ucb/echo -n "mailing account information..." mail -s "new account information" $administrator <<-END An NIS+ account for $full_name has just been created. Relevant information follows:

DATE: `date`

REALNAME: $full_name USERNAME: $user_name USER_ID: $uid GROUP_ID: $group ($gid) HOME_DIR: $home_dir

(this message automatically generated by $0) END echo done

exit

===================================================

This is from an old version of the Internet Relay Chat. just cc -O mkpasswd.c -o mkpasswd

-- john

/* simple password generator by Nelson Minar (minar@reed.edu) * copyright 1991, all rights reserved. * You can use this code as long as my name stays with it. */

#include <stdio.h> #include <stdlib.h> #include <string.h>

extern char *getpass();

int main(argc, argv) int argc; char *argv[]; { static char saltChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; char salt[3]; char * plaintext; int i;

if (argc < 2) { srandom(time(0)); /* may not be the BEST salt, but its close */ salt[0] = saltChars[random() % 64]; salt[1] = saltChars[random() % 64]; salt[2] = 0; } else { salt[0] = argv[1][0]; salt[1] = argv[1][1]; salt[2] = '\0'; if ((strchr(saltChars, salt[0]) == NULL) || (strchr(saltChars, salt[1]) == NULL)) fprintf(stderr, "illegal salt %s\n", salt), exit(1); }

plaintext = getpass("plaintext: ");

printf("%s\n", crypt(plaintext, salt)); return 0; }

================================================ Use crypt.. The first two characters is the seed...

int check_passwd (const char *user, const char *password) { char *pw; struct passwd *pass = user && *user ? getpwnam (user) : NULL; char salt[3];

if (pass && pass->pw_passwd) { salt[0] = (pass->pw_passwd)[0]; salt[1] = (pass->pw_passwd)[1]; salt[2] = 0; } else { return -1; }

pw = crypt (password, salt); return pw ? strcmp (pw, pass->pw_passwd) : -1; }

-- ______________________ <A HREF="whois://rs.internic.net/ecz">Edward C. Zimmermann</A> <A HREF="http://www.bsn.com/BSn">Basis Systeme netzwerk/Munich</A> ============================================== This works for me pwcrypt.c ---------------------------------%<----------------------------------- #include <stdio.h> #include <pwd.h> main () { char salt[2]; char pw_crypt[9]; fscanf(stdin, "%s%s", salt, pw_crypt); fprintf(stdout, "%s",crypt(pw_crypt, salt), 13 ); exit(0); }

---------------------------------%<----------------------------------- Syntax: pwcrypt plain_text_passwd salt

Jim McLean-Lipinski ================================================ Here is something I saved off the net a while back. Hope it does what you need.

Sanjiv -- Sanjiv K. Bhatia Department of Mathematics & Computer Science sanjiv@aryabhat.umsl.edu University of Missouri -- St. Louis voice: (314)-516-6520 St. Louis, MO 63121-4499 fax : (314)-516-5400 http://www.cs.umsl.edu/Faculty/sanjiv.html

----- /* From: Matthew Ball <matthewb@airport.bt.co.uk> */ /* Syntax: mkpasswd string It then echoes an encrypted passwd suitable for an /etc/passwd or /etc/shadow file. */

#include <stdio.h> #include <string.h>

main(argc,argv) int argc; char *argv[]; { char line[512],salt[3]; int i,l;

salt[2]='\0';

if(argc == 1) /* No parameters there read from standard input */ { while(gets(line) != NULL) { l=strlen(line); if(l > 2) { salt[0]=line[2]; salt[1]=line[1]; printf("%s\n",crypt(line,salt)); } else fprintf(stderr,"Too short [%i] \"%s\"\n",l,line); } } else { for(i=1;i<argc;i++) { l=strlen(argv[i]); if(l > 2) { salt[0]=argv[i][2]; salt[1]=argv[i][1]; printf("%s\n",crypt(argv[i],salt)); } else fprintf(stderr,"Too short [%i] \"%s\"\n",l,argv[i]); } } }



This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:10:58 CDT