pwconv.c revision 42487ff1899d230ad6c2d55cf9573489ca5eb770
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#pragma ident "%Z%%M% %I% %E% SMI"
/* pwconv.c */
/* Conversion aid to copy appropriate fields from the */
/* password file to the shadow file. */
#include <pwd.h>
#include <fcntl.h>
#include <stdio.h>
#include <time.h>
#include <shadow.h>
#include <grp.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>
#define PRIVILEGED 0 /* priviledged id */
/* exit code */
#define SUCCESS 0 /* succeeded */
char *prognamp;
/*
* getspnan routine that ONLY looks at the local shadow file
*/
struct spwd *
local_getspnam(char *name)
{
return (NULL);
break;
}
return (sp);
}
int
{
extern int errno;
void no_recover(void), no_convert(void);
int file_exist = 1;
int end_of_file = 0;
int pwerr = 0;
ushort_t i;
int black_magic = 0;
int count;
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
#define TEXT_DOMAIN "SYS_TEST"
#endif
(void) textdomain(TEXT_DOMAIN);
/* only PRIVILEGED can execute this command */
if (getuid() != PRIVILEGED) {
prognamp);
}
/* No argument can be passed to the command */
if (argc > 1) {
gettext("%s: Invalid command syntax.\n"),
prognamp);
}
/* lock file so that only one process can read or write at a time */
if (lckpwdf() < 0) {
gettext("%s: Password file(s) busy. Try again later.\n"),
prognamp);
}
/* All signals will be ignored during the execution of pwconv */
for (i = 1; i < NSIG; i++)
/* reset errno to avoid side effects of a failed */
/* sigset (e.g., SIGKILL) */
errno = 0;
/* check the file status of the password file */
/* get the gid of the password file */
(void) f_miss();
}
/* mode for the password file should be read-only or less */
/* open temporary password file */
(void) f_err();
}
DELPTMP();
(void) f_err();
}
/* default mode mask of the shadow file */
/* check the existence of shadow file */
/* if the shadow file exists, get mode mask and group id of the file */
/* if file does not exist, the default group name will be the group */
/* name of the password file. */
} else {
DELPTMP();
(void) f_err();
}
} else {
file_exist = 0;
}
/*
* get the mode of shadow password file -- mode of the file should
* be read-only for user or less.
*/
/* open temporary shadow file */
DELPTMP();
(void) f_err();
}
/* change the group of the temporary shadow password file */
(void) no_convert();
}
/* Reads the password file. */
/* If the shadow password file not exists, or */
/* if an entry doesn't have a corresponding entry in */
no_recover();
}
count = 0;
while (!end_of_file) {
count++;
if (!file_exist ||
/* Bad entry in shadow exit */
DELSHWTMP();
DELPTMP();
(void) f_bdshw();
}
gettext("%s: WARNING user %s has no password\n"),
}
/*
* copy the password field in the password
* file to the shadow file.
* replace the password field with an 'x'.
*/
/*
* if aging, split the aging info
* into age, max and min
* convert aging info from weeks to days
*/
when >>= 12;
} else {
/*
* if !aging, last_changed will be the day the
* conversion is done, min and max fields will
* be null - use timezone to get local time
*/
}
} else {
/*
* if the passwd field has a string other than 'x',
* the entry will be written into the shadow file
* and the character 'x' is re-written as the passwd
* if !aging, last_changed as above
*/
/*
* with NIS, only warn about password missing if entry
* is not a NIS-lookup entry ("+" or "-")
* black_magic from getpwnam_r.c
*/
/*
* moan about absence of non "+/-" passwd
* we could do more, but what?
*/
!black_magic) {
gettext("%s: WARNING user %s has no password\n"),
}
}
}
} else {
/*
* black_magic needs a non-null passwd
* and pwdflr seem appropriate here
* clear garbage if any
*/
}
/*
* if aging, split the aging info
* into age, max and min
* convert aging info from weeks to days
*/
when >>= 12;
}
}
/* write an entry to temporary password file */
(void) no_convert();
}
/* write an entry to temporary shadow password file */
(void) no_convert();
}
} else {
end_of_file = 1;
} else {
errno = 0;
pwerr = 1;
gettext("%s: ERROR: bad entry or blank "
}
}
} /* end of while */
if (pwerr) {
(void) no_convert();
}
/* delete old password file if it exists */
(void) no_convert();
}
/* rename the password file to old password file */
(void) no_convert();
}
/* rename temporary password file to password file */
/* link old password file to password file */
(void) no_recover();
}
(void) no_convert();
}
/* delete old shadow password file if it exists */
/* link old password file to password file */
(void) no_recover();
}
(void) no_convert();
}
/* link shadow password file to old shadow password file */
/* link old password file to password file */
(void) no_recover();
}
(void) no_convert();
}
/* link temporary shadow password file to shadow password file */
/* link old shadow password file to shadow password file */
(void) no_recover();
}
(void) no_recover();
}
(void) no_convert();
}
/* Make new mode same as old */
/* Change old password file to read only by owner */
/* If chmod fails, delete the old password file so that */
/* the password fields can not be read by others */
(void) ulckpwdf();
return (0);
}
void
no_recover(void)
{
DELPTMP();
DELSHWTMP();
(void) f_miss();
}
void
no_convert(void)
{
DELPTMP();
DELSHWTMP();
(void) f_err();
}
void
f_err(void)
{
gettext("%s: Unexpected failure. Conversion not done.\n"),
prognamp);
(void) ulckpwdf();
}
void
f_miss(void)
{
gettext("%s: Unexpected failure. Password file(s) missing.\n"),
prognamp);
(void) ulckpwdf();
}
void
f_bdshw(void)
{
prognamp);
(void) ulckpwdf();
}