/*
* Copyright (c) 1987, 1993, 1994, 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* Everything below this point is intended for the convenience of programs
* which allow a user to interactively edit the passwd file. Errors in the
* routines below will cause the process to abort. */
switch(editpid = vfork()) {
case -1:
free(p);
return;
case 0:
if (notsetuid) {
setgid(getgid());
setuid(getuid());
}
execvp(_PATH_BSHELL, (char *const *)__UNCONST(argp));
_exit(1);
}
free(p);
for (;;) {
editpid = waitpid(editpid, (int *)&pstat, WUNTRACED);
if (editpid == -1)
pw_error(editor, 1, 1);
else if (WIFSTOPPED(pstat))
raise(WSTOPSIG(pstat));
else if (WIFEXITED(pstat) && WEXITSTATUS(pstat) == 0)
break;
else
pw_error(editor, 1, 1);
}
editpid = -1;
}
void
pw_prompt(void)
{
int c;
(void)printf("re-edit the password file? [y]: ");
(void)fflush(stdout);
c = getchar();
if (c != EOF && c != '\n')
while (getchar() != '\n');
if (c == 'n')
pw_error(NULL, 0, 0);
}
/* for use in pw_copy(). Compare a pw entry to a pw struct. */
/* returns a character string labelling the miscompared field or 0 */
static const char *
pw_equal(char *buf, struct passwd *pw)
{
struct passwd buf_pw;
size_t len;
/* Handle empty string */
if (*line == '\0')
return;
/* Remove leading spaces */
p = line;
while (isspace((unsigned char) *p))
p++;
memmove(line, p, strlen(p) + 1);
/* Handle empty string after removal of whitespace characters */
if (*line == '\0')
return;
/* Remove trailing spaces, line must not be empty string here */
p = line + strlen(line) - 1;
while (isspace((unsigned char) *p))
p--;
*(p + 1) = '\0';
}
/* Get one line, remove spaces from front and tail */
static int
read_line(FILE *fp, char *line, int max)
{
char *p;
_DIAGASSERT(option != NULL);
for (i = 0; i < sizeof(options) / sizeof(options[0]); i++)
if (strcmp(options[i][0], option) == 0)
return (options[i][1]);
return (NULL);
}
/*
* Retrieve password information from the /etc/passwd.conf file, at the
* moment this is only for choosing the cipher to use. It could easily be
* used for other authentication methods as well.
*/
void
pw_getconf(char *data, size_t max, const char *key, const char *option)
{
FILE *fp;
char line[LINE_MAX], *p, *p2;
static char result[LINE_MAX];
int got, found;
const char *cp;