NFSv2/usr/src/usr.bin/yppasswd.c
#ifndef lint
static char sccsid[] = "@(#)yppasswd.c 1.1 85/05/31 Copyr 1985 Sun Micro";
#endif
/*
* Copyright (c) 1985 by Sun Microsystems, Inc.
*/
#include <stdio.h>
#include <signal.h>
#include <pwd.h>
#include <rpc/rpc.h>
#include <rpcsvc/yppasswd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <errno.h>
char *getmaster(), *index();
struct yppasswd *getyppw();
main(argc, argv)
char **argv;
{
int ans, port, ok;
char *master;
struct yppasswd *yppasswd;
master = getmaster();
#ifdef DEBUG
fprintf(stderr, "master is %s\n", master);
master = "sundae";
#endif
port = getport(master);
if (port == 0) {
fprintf(stderr, "%s is not running yppasswd demon\n", master);
exit(1);
}
if (port >= IPPORT_RESERVED) {
fprintf(stderr,
"yppasswd daemon is not running on privileged port\n");
exit(1);
}
yppasswd = getyppw(argc, argv);
ans = callrpc(master, YPPASSWDPROG, YPPASSWDVERS,
YPPASSWDPROC_UPDATE, xdr_yppasswd, yppasswd, xdr_int, &ok);
if (ans != 0) {
clnt_perrno(ans);
fprintf(stderr, "\n");
fprintf(stderr, "couldn't change passwd\n");
}
else if (ok != 0)
fprintf(stderr, "couldn't change passwd\n");
else
printf("yellow pages passwd changed on %s\n", master);
}
char *
getmaster()
{
char domain[256];
char *val, *p;
int vallen;
if (getdomainname(domain, sizeof(domain)) < 0) {
fprintf(stderr, "getdomainname system call not implemented\n");
exit(1);
}
if (yp_match(domain, "ypmaps", "passwd.byname",
strlen("passwd.byname"), &val, &vallen)) {
fprintf(stderr, "can't find passwd master\n");
exit(1);
}
p = index(val, '\n');
if (p)
*p = 0;
return (val);
}
getport(host)
char *host;
{
struct sockaddr_in addr;
struct hostent *hp;
if ((hp = gethostbyname(host)) == NULL) {
fprintf(stderr, "%s is unknown host\n", host);
exit(1);
}
bcopy(hp->h_addr, &addr.sin_addr, hp->h_length);
addr.sin_family = AF_INET;
addr.sin_port = 0;
return (pmap_getport(&addr, YPPASSWDPROG, YPPASSWDPROC_UPDATE,
IPPROTO_UDP));
}
struct passwd *pwd;
struct passwd *getpwent();
int endpwent();
char *strcpy();
char *crypt();
char *getpass();
char *getlogin();
char *pw;
char pwbuf[10];
char pwbuf1[10];
char hostname[256];
extern int errno;
struct yppasswd *
getyppw(argc, argv)
char *argv[];
{
char *p;
int i;
char saltc[2];
long salt;
int u;
int insist;
int ok, flags;
int c, pwlen;
char *uname;
static struct yppasswd yppasswd;
insist = 0;
uname = NULL;
if (argc > 1)
uname = argv[1];
if (uname == NULL) {
if ((uname = getlogin()) == NULL) {
fprintf(stderr, "you don't have a login name\n");
exit(1);
}
gethostname(hostname, sizeof(hostname));
printf("Changing yp password for %s\n", uname);
}
while (((pwd = getpwent()) != NULL) && strcmp(pwd->pw_name, uname))
;
u = getuid();
if (pwd == NULL) {
printf("Not in passwd file.\n");
exit(1);
}
if (u != 0 && u != pwd->pw_uid) {
printf("Permission denied.\n");
exit(1);
}
endpwent();
strcpy(pwbuf1, getpass("Old yp password:"));
tryagain:
strcpy(pwbuf, getpass("New password:"));
pwlen = strlen(pwbuf);
if (pwlen == 0) {
printf("Password unchanged.\n");
exit(1);
}
/*
* Insure password is of reasonable length and
* composition. If we really wanted to make things
* sticky, we could check the dictionary for common
* words, but then things would really be slow.
*/
ok = 0;
flags = 0;
p = pwbuf;
while (c = *p++) {
if (c >= 'a' && c <= 'z')
flags |= 2;
else if (c >= 'A' && c <= 'Z')
flags |= 4;
else if (c >= '0' && c <= '9')
flags |= 1;
else
flags |= 8;
}
if (flags >= 7 && pwlen >= 4)
ok = 1;
if ((flags == 2 || flags == 4) && pwlen >= 6)
ok = 1;
if ((flags == 3 || flags == 5 || flags == 6) && pwlen >= 5)
ok = 1;
if (!ok && insist < 2) {
printf("Please use %s.\n", flags == 1 ?
"at least one non-numeric character" :
"a longer password");
insist++;
goto tryagain;
}
if (strcmp(pwbuf, getpass("Retype new password:")) != 0) {
printf("Mismatch - password unchanged.\n");
exit(1);
}
time(&salt);
salt = 9 * getpid();
saltc[0] = salt & 077;
saltc[1] = (salt>>6) & 077;
for (i = 0; i < 2; i++) {
c = saltc[i] + '.';
if (c > '9')
c += 7;
if (c > 'Z')
c += 6;
saltc[i] = c;
}
pw = crypt(pwbuf, saltc);
yppasswd.oldpass = pwbuf1;
pwd->pw_passwd = pw;
yppasswd.newpw = *pwd;
return (&yppasswd);
}