How to make an encrypt. Password
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 (egmachine1@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]);
}
}
}

