Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37501005
en ru br
Репозитории ALT
S:1.0.14-alt1
5.1: 1.0.12-alt2
4.1: 1.0.12-alt2
4.0: 1.0.12-alt2
3.0: 1.0.7-alt2
www.altlinux.org/Changes

Группа :: Система/Основа
Пакет: passwd

 Главная   Изменения   Спек   Патчи   Исходники   Загрузить   Gear   Bugs and FR  Repocop 

passwd-1.0.12/000075500000000000000000000000001061016041700130665ustar00rootroot00000000000000passwd-1.0.12/.gitignore000064400000000000000000000000271061016041700150550ustar00rootroot00000000000000passwd
tmp
wrapper
*.8
passwd-1.0.12/Makefile000064400000000000000000000037711061016041700145360ustar00rootroot00000000000000#
# Copyright (C) 2003-2006 Dmitry V. Levin <ldv@altlinux.org>
#
# Makefile for the passwd project.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#

PROJECT = passwd
VERSION = $(shell sed '/^Version: */!d;s///;q' passwd.spec)
MAN8PAGES = $(PROJECT).8
TARGETS = $(PROJECT) wrapper $(MAN8PAGES)

DESTDIR =
libdir=/usr/lib
bindir=/usr/bin
sbindir=/usr/sbin
mandir=/usr/share/man
pamdir=/etc/pam.d
facdir=/etc/control.d/facilities

CPPFLAGS = -D_GNU_SOURCE -DPROJECT_VERSION=\"$(VERSION)\"
CFLAGS = -pipe -Wall -Werror -W -O2
LDLIBS = -lpam $(shell test -f $(libdir)/libpam_misc.so && echo -lpam_misc)
LDFLAGS = -Wl,--as-needed

LN_S = ln -sf
MKDIR_P = mkdir -p
INSTALL = install
HELP2MAN = help2man -N -s8 -i $(PROJECT).inc

.PHONY: all install clean indent

all: $(TARGETS)

$(PROJECT).8: wrapper $(PROJECT).inc
$(MKDIR_P) tmp
$(LN_S) ../$< tmp/$(PROJECT)
$(HELP2MAN) ./tmp/$(PROJECT) > $@

install:
$(INSTALL) -pD -m755 $(PROJECT) $(DESTDIR)$(bindir)/$(PROJECT)
$(INSTALL) -pD -m700 wrapper $(DESTDIR)$(sbindir)/$(PROJECT)
$(INSTALL) -pD -m644 $(PROJECT).1 $(DESTDIR)$(mandir)/man1/$(PROJECT).1
$(INSTALL) -pD -m644 $(PROJECT).8 $(DESTDIR)$(mandir)/man8/$(PROJECT).8
$(INSTALL) -pD -m640 $(PROJECT).pamd $(DESTDIR)$(pamdir)/$(PROJECT)
$(INSTALL) -pD -m755 $(PROJECT).control $(DESTDIR)$(facdir)/$(PROJECT)

clean:
$(RM) $(TARGETS) *~ core
$(RM) -r tmp

indent:
indent *.c

passwd-1.0.12/passwd.1000064400000000000000000000070461061016041700144600ustar00rootroot00000000000000.\" Hey Emacs! This file is -*- nroff -*- source.
.\" (above from Rik Faith..:*)
.\" Copyright (c) Andrew G. Morgan 1996, <morgan at linux.kernel.org>
.\" Updated for Owl by Solar Designer <solar at openwall.com>
.\" Updated for ALT Linux by Dmitry V. Levin <ldv at altlinux.org>
.\"
.TH PASSWD 1 "2006 Sep 4" "ALT Linux Team" "ALT Linux"

.SH NAME
passwd \- update a user's authentication tokens(s)

.SH SYNOPSIS
.B passwd [-h] [-k] [username]

.SH DESCRIPTION
Passwd is used to update a user's authentication token(s).

Passwd is configured to work through the
.BR "PAM API" .
Essentially, it initializes itself as a "passwd" service with
.B PAM
and utilizes configured
.I "password"
modules to authenticate and then update a user's password.

Only the superuser may update another user's password by supplying a different
.BR username .

.SH OPTIONS

.IP \fB-k\fR
This option is used to indicate that the update should only be for expired
authentication tokens (passwords); the user wishes to keep their
non-expired tokens as before.

.IP \fB-h\fR
Print short usage text and exit.

.SH "Remember the following two principles"

.IP \fBProtect\ your\ password\fR.
Don't write down your password - memorize it.
In particular, don't write it down and leave it anywhere, and don't
place it in an unencrypted file! Use unrelated passwords for systems
controlled by different organizations. Don't give or share your password,
in particular to someone claiming to be from computer support or a
vendor. Don't let anyone watch you enter your password. Don't enter
your password to a computer you don't trust or if things \"look funny\";
someone may be trying to hijack your password. Use the password for a
limited time and change it periodically.

.IP \fBChoose\ a\ hard-to-guess\ password\fR.
.I passwd
will try to prevent you from choosing a really bad password, but it
isn't foolproof; create your password wisely. Don't use something
you'd find in a dictionary (in any language or jargon). Don't use a name
(including that of a spouse, parent, child, pet, fantasy character, famous
person, and location) or any variation of your personal or account name.
Don't use accessible information about you (such as your phone number,
license plate, or social security number) or your environment. Don't use
a birthday or a simple pattern (such as \"qwerty\", \"abc\", or \"aaa\").
Don't use any of those backwards, followed by a digit, or preceded
by a digit. Instead, use a mixture of upper and lower case letters,
as well as digits or punctuation. When choosing a new password, make
sure it's unrelated to any previous password. Use long passwords (say 8
characters long). You might use a word pair with punctuation inserted,
a passphrase (an understandable sequence of words), or the first letter
of each word in a passphrase.

.SH ""
These principles are partially enforced by the system, but only partly so.
Vigilence on your part will make the system much more secure.

.SH "EXIT CODE"

On successful completion of its task,
.B passwd
will complete with exit code 0. An exit code of 1 indicates an error
occurred. Textual errors are written to the standard error stream.

.SH "CONFORMING TO"
.br
.BR Linux-PAM ,
.BR OpenPAM .

.SH "FILES"
.br
.B /etc/pam.d/passwd
- the
.B PAM
passwd configuration file.

.SH "SEE ALSO"
.BR pam (8),
.BR pam_chauthtok (3).

For more complete information on how to configure this application
with
.BR Linux-PAM ,
see the
.BR "Linux-PAM System Administrators' Guide" " at"
.I "/usr/share/doc/Linux-PAM*/html/Linux-PAM_SAG.html"

.SH AUTHOR
Andrew G. Morgan <morgan at kernel.org>
passwd-1.0.12/passwd.c000064400000000000000000000111311061016041700145300ustar00rootroot00000000000000
/*
*
* passwd.c
*
* Written for Linux-PAM by Andrew G. Morgan <morgan@linux.kernel.org>
* Modified by Solar Designer <solar@owl.openwall.com>
* Modified by Dmitry V. Levin <ldv@altlinux.org>
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdarg.h>
#include <errno.h>
#include <fcntl.h>
#include <syslog.h>
#include <pwd.h>
#include <sys/stat.h>

#include <security/pam_misc.h>

static struct pam_conv conv = {
misc_conv,
NULL
};

#define PASSWD_SERVICE "passwd"
#define PASSWD_FAIL_DELAY 2000000 /* usec delay on failure */

static void
fix_fds(void)
{
struct stat st;

if (fstat(STDOUT_FILENO, &st) < 0)
{
int fd = open("/dev/null", O_WRONLY);

if (fd < 0)
exit(EXIT_FAILURE);
if (fd != STDOUT_FILENO)
{
if (dup2(fd, STDOUT_FILENO) != STDOUT_FILENO)
exit(EXIT_FAILURE);
if (close(fd) < 0)
exit(EXIT_FAILURE);
}
}

if (fstat(STDERR_FILENO, &st) < 0)
{
int fd = open("/dev/null", O_WRONLY);

if (fd < 0)
exit(EXIT_FAILURE);
if (fd != STDERR_FILENO)
{
if (dup2(fd, STDERR_FILENO) != STDERR_FILENO)
exit(EXIT_FAILURE);
if (close(fd) < 0)
exit(EXIT_FAILURE);
}
}
}

static void
__attribute__ ((noreturn, format(printf, 1, 2)))
show_usage(const char *fmt, ...)
{
fprintf(stderr, "%s: ", program_invocation_short_name);

va_list arg;

va_start(arg, fmt);
vfprintf(stderr, fmt, arg);
va_end(arg);

fprintf(stderr, ".\nTry `%s --help' for more information.\n",
program_invocation_short_name);
exit(EXIT_FAILURE);
}

static void
__attribute__ ((__noreturn__))
show_help(void)
{
printf("Passwd is used to update a user's authentication token(s).\n\n"
"Usage: %s [options] [username]\n\n"
"Valid options and arguments are:\n"
" -h or --help - print this help text and exit;\n"
" -k - keep non-expired authentication tokens;\n"
" username - update tokens for named user.\n",
program_invocation_short_name);
exit(EXIT_SUCCESS);
}

static int
parse_pass_args(int ac, const char **av, const char **user)
{
int pam_flags = 0, i;

*user = 0;

if (ac < 1)
show_usage("Insufficient arguments");

for (i = 1; i < ac; ++i)
{
if (av[i][0] == '-')
{
/* options. */

if (!strcmp(av[i], "-h") || !strcmp(av[i], "--help"))
show_help();

if (av[i][1] == 'k' && !av[i][2])
pam_flags = PAM_CHANGE_EXPIRED_AUTHTOK;
else
show_usage("%s: Invalid option", av[i]);
} else
{
if (*user)
show_usage("%s: Too many arguments", av[i]);
else
*user = av[i];
}
}

return pam_flags;
}

static const char *
get_user(const char *user)
{
uid_t uid = getuid();
struct passwd *pwent;

if (!user)
user = getlogin();

if (!user)
pwent = getpwuid(uid);
else
{
pwent = getpwnam(user);
if (uid && (!pwent || pwent->pw_uid != uid))
{
fprintf(stderr,
"passwd: only superuser can give different username.\n");
exit(EXIT_FAILURE);
}
}

endpwent();

if (!pwent || !pwent->pw_name)
{
fprintf(stderr, "passwd: cannot retrieve username.\n");
exit(EXIT_FAILURE);
}

user = strdup(pwent->pw_name);
if (!user)
{
fprintf(stderr, "passwd: out of memory.\n");
exit(EXIT_FAILURE);
}

return user;
}

static void
__attribute__ ((__noreturn__))
failure(pam_handle_t * pamh, int retval)
{
if (pamh)
{
fprintf(stderr, "passwd: %s.\n", pam_strerror(pamh, retval));
pam_end(pamh, retval);
}

exit(EXIT_FAILURE);
}

int
main(int ac, const char **av)
{
const char *user = 0;
int pam_flags, retval;
pam_handle_t *pamh = 0;

fix_fds();

pam_flags = parse_pass_args(ac, av, &user);

user = get_user(user);

setlinebuf(stdout);

openlog(PASSWD_SERVICE, LOG_PID, LOG_AUTHPRIV);

retval = pam_start(PASSWD_SERVICE, user, &conv, &pamh);
if (PAM_SUCCESS != retval)
failure(pamh, retval);

#ifdef HAVE_PAM_FAIL_DELAY
retval = pam_fail_delay(pamh, PASSWD_FAIL_DELAY);
if (PAM_SUCCESS != retval)
{
fprintf(stderr, "passwd: unable to set failure delay.\n");
pam_end(pamh, retval);
exit(EXIT_FAILURE);
}
#endif /* HAVE_PAM_FAIL_DELAY */

/*
* The user is authenticated by the passwd module;
* change the password(s) too.
*/

if (!getuid())
fprintf(stderr,
"passwd: updating %s authentication tokens for user %s.\n",
pam_flags ? "expired" : "all", user);

retval = pam_chauthtok(pamh, pam_flags);
if (PAM_SUCCESS != retval)
failure(pamh, retval);

/* All done. */

retval = pam_end(pamh, PAM_SUCCESS);
if (PAM_SUCCESS != retval)
failure(pamh, retval);

/* Quit gracefully. */

fprintf(stderr,
"passwd: %s authentication tokens updated successfully.\n",
pam_flags ? "expired" : "all");

return PAM_SUCCESS;
}
passwd-1.0.12/passwd.control000064400000000000000000000014671061016041700160010ustar00rootroot00000000000000#!/bin/sh

. /etc/control.d/functions

BINARY=/usr/bin/passwd
CONFIG=/etc/pam.d/passwd

new_summary "passwd utility for updating passwords using PAM"

new_fmode tcb 2711 root shadow
new_fmode traditional 4711 root root
new_fmode restricted 700 root root

new_help tcb "Any user can change his own password using $BINARY when tcb scheme is enabled"
new_help traditional "Any user can change his own password using $BINARY when tcb scheme is disabled"
new_help restricted "Only root may change users passwords using $BINARY"

# Backwards compatibility
test "$*" = public && set - tcb

control_fmode "$BINARY" "$*" || exit 1
is_builtin_mode "$*" && exit 0

new_fmode tcb_config 640 root shadow
new_fmode traditional_config 600 root root
new_fmode restricted_config 600 root root

control_fmode "$CONFIG" "$*_config" || exit 1
passwd-1.0.12/passwd.inc000064400000000000000000000011011061016041700150530ustar00rootroot00000000000000
[NAME]
passwd wrapper

[EXIT CODE]
On successful completion of its task,
.B passwd
will complete with exit code 0. An exit code of 1 indicates an error
occurred. Textual errors are written to the standard error stream.

[SEE ALSO]
.BR passwd (1),
.BR chpasswd (8),
.BR usermod (8).

[AUTHOR]
Written by Dmitry V. Levin <ldv@altlinux.org>

[COPYRIGHT]
Copyright \(co 2002, 2003, 2004 Dmitry V. Levin <ldv@altlinux.org>
.br
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
passwd-1.0.12/passwd.pamd000064400000000000000000000001771061016041700152370ustar00rootroot00000000000000#%PAM-1.0
auth include system-auth
account include system-auth
password include system-auth
session required pam_deny.so
passwd-1.0.12/passwd.spec000064400000000000000000000100651061016041700152450ustar00rootroot00000000000000Name: passwd
Version: 1.0.12
Release: alt2

Summary: The passwd utility for setting/changing passwords using PAM
License: GPL
Group: System/Base
Packager: Dmitry V. Levin <ldv@altlinux.org>

Source: passwd-%version.tar

PreReq: /etc/tcb, shadow-utils >= 1:4.0.0-alt3, control

BuildPreReq: libpam-devel, help2man

%description
This package contains a system utility (passwd) which is used to update
a user's authentication token(s).

%prep
%setup -q

%build
%make_build CFLAGS="%optflags -W -Werror" libdir=%_libdir

%install
%make_install install DESTDIR=%buildroot libdir=%_libdir

%pre
%pre_control passwd

%post
%post_control -s tcb passwd

%files
%attr(600,root,root) %verify(not mode group) %config(noreplace) %_sysconfdir/pam.d/passwd
%config %_controldir/passwd
%attr(700,root,root) %verify(not mode group) %_bindir/passwd
%_sbindir/passwd
%_mandir/man?/passwd.*

%changelog
* Sat Apr 14 2007 Dmitry V. Levin <ldv@altlinux.org> 1.0.12-alt2
- Reduced macro abuse in specfile.

* Mon Sep 04 2006 Dmitry V. Levin <ldv@altlinux.org> 1.0.12-alt1
- passwd.1: Cleaned up, updated references.

* Sat Apr 29 2006 Dmitry V. Levin <ldv@altlinux.org> 1.0.11-alt1
- Added summary to control script.

* Thu Jan 12 2006 Dmitry V. Levin <ldv@altlinux.org> 1.0.10-alt1
- Link using --as-needed option to avoid linking with unused libraries.

* Mon Oct 03 2005 Dmitry V. Levin <ldv@altlinux.org> 1.0.9-alt1
- Fixed build with new Linux-PAM.
- Enhanced usage and help output.

* Thu Aug 11 2005 Dmitry V. Levin <ldv@altlinux.org> 1.0.8-alt1
- passwd utility: initialize system logger.
- passwd wrapper: use program_invocation_short_name
instead of __progname.

* Wed Apr 20 2005 Dmitry V. Levin <ldv@altlinux.org> 1.0.7-alt2
- Instructed RPM to not verify permissions and group ownership
of files which are controlled via control(8) facility.

* Fri Feb 11 2005 Dmitry V. Levin <ldv@altlinux.org> 1.0.7-alt1
- Fixed build on x86_64 platform.

* Sat Sep 25 2004 Dmitry V. Levin <ldv@altlinux.org> 1.0.6-alt1
- Updated manpage and control script.

* Sun Jan 18 2004 Dmitry V. Levin <ldv@altlinux.org> 1.0.5-alt1
- passwd(8): use help2man to generate manpage from template.
- wrapper: deal with compilation warnings produced by -W.

* Tue Jun 17 2003 Dmitry V. Levin <ldv@altlinux.org> 1.0.4-alt1
- Fixed build with OpenPAM.
- Added Linux-PAM/OpenPAM multi-build support.

* Fri May 23 2003 Dmitry V. Levin <ldv@altlinux.org> 1.0.3-alt1
- PAM configuration policy enforcement.

* Sun Jan 12 2003 Dmitry V. Levin <ldv@altlinux.org> 1.0.2-alt1
- Be more verbose about username we are changing auth information for.
- Support "traditional" and "tcb" settings for permissions on
/usr/bin/passwd and /etc/pam.d/passwd (Owl).
- Keep passwd at mode "restricted" in the package, but default it
to "tcb" in %%post when the package is first installed.
This avoids a race and fail-open behavior (inspired by Owl).

* Sun Oct 13 2002 Dmitry V. Levin <ldv@altlinux.org> 1.0.1-alt1
- Added control support for passwd.

* Thu Feb 07 2002 Dmitry V. Levin <ldv@alt-linux.org> 1.0.0-alt1
- Rewritten root passwd wrapper.

* Fri Dec 14 2001 Dmitry V. Levin <ldv@alt-linux.org> 0.64.1-ipl5mdk
- Switched to tcb.

* Fri Sep 07 2001 Dmitry V. Levin <ldv@altlinux.ru> 0.64.1-ipl4mdk
- Updated pam configuration.
- Rebuilt to get more dependencies.

* Tue Sep 04 2001 Dmitry V. Levin <ldv@altlinux.ru> 0.64.1-ipl3mdk
- Merged with RH (release 7).
- passwd have been split into
+ %_bindir/passwd - privileged utility for users;
+ %_sbindir/passwd - unpriviliged utility for administrator.
The code of %_bindir/passwd is rewrite of passwd utility
from SimplePAMApps package.
There are two diffirent manpages for these utilities now.

* Fri Feb 23 2001 Dmitry V. Levin <ldv@fandra.org> 0.64.1-ipl2mdk
- Added progname patch.

* Fri Oct 13 2000 Dmitry V. Levin <ldv@fandra.org> 0.64.1-ipl1mdk
- Merged with RH (release 4).
- RE adaptions.

* Tue Apr 4 2000 Dmitry V. Levin <ldv@fandra.org>
- 0.64.1

* Sun Oct 24 1999 Dmitry V. Levin <ldv@fandra.org>
- Fandra adaptions

* Sat Apr 10 1999 Cristian Gafton <gafton@redhat.com>
- first build from the new source code base.
passwd-1.0.12/wrapper.c000064400000000000000000000157061061016041700147230ustar00rootroot00000000000000
/*
*
* passwd wrapper - implements traditional passwd options using
* real passwd utility or shadow utils.
*
* Copyright (C) 2002, 2004, 2005 Dmitry V. Levin <ldv@altlinux.org>
*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <errno.h>
#include <argp.h>
#include <pwd.h>
#include <shadow.h>

static void
__attribute__ ((__noreturn__, __format__ (__printf__, 2, 3)))
failure (int errnum, const char *fmt, ...)
{
va_list args;

fflush (stdout);
fprintf (stderr, "%s: ", program_invocation_short_name);
va_start (args, fmt);
vfprintf (stderr, fmt, args);
va_end (args);
if (errnum)
fprintf (stderr, ": %s", strerror (errnum));
putc ('\n', stderr);
fflush (stderr);

exit (EXIT_FAILURE);
}

static void
__attribute__ ((__noreturn__))
fail_username (void)
{
fprintf (stderr,
"%s: this operation requires username to be specified.\n",
program_invocation_short_name);

exit (EXIT_FAILURE);
}

#define OPT_STDIN 0x13

const char *argp_program_version = "passwd wrapper version " PROJECT_VERSION;

const char *argp_program_bug_address = "http://bugs.altlinux.ru/";

/* Short description of program. */
static const char doc[] =
"passwd wrapper implements traditional passwd options using real passwd utility or shadow utils.";

/* Strings for arguments in help texts. */
static const char args_doc[] = "[USERNAME]";

/* The options we understand. */
static struct argp_option options[] = {
{0, 0, 0, 0, "Valid options are:", 0},
{"delete", 'd', 0, 0, "Delete the password for the specified account", 0},
{"force", 'f', 0, 0, "Force operation", 0},
{"keep-tokens", 'k', 0, 0, "Keep non-expired authentication tokens", 0},
{"lock", 'l', 0, 0, "Lock the specified account", 0},
{"unlock", 'u', 0, 0, "Unlock the specified account", 0},
{"status", 'S', 0, 0, "Report password status on the specified account", 0},
{"stdin", OPT_STDIN, 0, 0, "Read new tokens from stdin", 1},
{0, 0, 0, 0, 0, 0}
};

typedef int (*DO_FPTR) (void);
DO_FPTR do_fun;

static int is_keep;
const char *username;

static int
chpasswd (const char *passwd)
{
FILE *fp;
const char *path = "/usr/sbin/chpasswd";

if (!username)
fail_username ();

fp = popen (path, "w");
if (!fp)
failure (errno, "popen: %s", path);

if (fprintf (fp, "%s:%s\n", username, passwd) !=
(int)(2 + strlen (username) + strlen (passwd)))
failure (errno, "fprintf");

if (pclose (fp) < 0)
failure (errno, "pclose");

return EXIT_SUCCESS;
}

static int
do_stdin (void)
{
size_t len;
char buf[BUFSIZ];

if (!username)
fail_username ();

if (!fgets (buf, sizeof (buf), stdin))
failure (errno, "error reading password");

len = strlen (buf);
if (len > 0 && ('\n' == buf[len - 1]))
buf[len - 1] = '\0';

return chpasswd (buf);
}

static int
do_delete (void)
{
return chpasswd ("");
}

static void
__attribute__ ((__noreturn__))
lock_unlock (const char *param)
{
const char *path = "/usr/sbin/usermod";
size_t argc = 0;
const char *argv[4];

if (!username)
fail_username ();

argv[argc++] = "usermod";
argv[argc++] = param;
argv[argc++] = username;
argv[argc] = 0;

execv (path, (char *const *) argv);
failure (errno, "execv: %s", path);
}

static int
do_lock (void)
{
lock_unlock ("-L");
}

static int
do_unlock (void)
{
lock_unlock ("-U");
}

static int
do_status (void)
{
struct passwd *pw;
struct spwd *spw;
const char *hash = 0, *p;

if (!username)
fail_username ();

pw = getpwnam (username);
endpwent ();
if (!pw)
failure (0, "user \"%s\" not found.", username);

hash = pw->pw_passwd;

if (!strcmp (hash, "x"))
{
spw = getspnam (username);
endspent ();
if (!spw)
failure (errno,
"error reading user \"%s\" shadow entry",
username);

hash = spw->sp_pwdp;
} else if (!strcmp (hash, "*NP*"))
{
uid_t old_uid;

old_uid = geteuid ();
seteuid (pw->pw_uid);
spw = getspnam (username);
endspent ();
seteuid (old_uid);

if (!spw)
failure (errno,
"error reading user \"%s\" shadow entry",
username);

hash = spw->sp_pwdp;
}

if (!hash || !hash[0])
{
puts ("Empty password.");
return EXIT_SUCCESS;
}

if ('*' == hash[0] || !strcmp ("x", hash) || !strcmp ("!!", hash))
{
puts ("No Password set.");
return EXIT_SUCCESS;
}

if ('!' == hash[0])
{
if (!hash[1])
{
puts ("Locked Empty password.");
return EXIT_SUCCESS;
}
printf ("Locked password, ");
p = hash + 1;
} else
{
printf ("Password set, ");
p = hash;
}

if (!strncmp (p, "$2a$", 4))
puts ("blowfish encryption.");
else if (!strncmp (p, "$1$", 3))
puts ("MD5 encryption.");
else if ('_' == p[0])
puts ("BSDI encryption.");
else if ('$' == p[0])
puts ("unknown encryption.");
else
puts ("DES encryption.");

return EXIT_SUCCESS;
}

static int
do_plain (void)
{
const char *path = "/usr/bin/passwd";
size_t argc = 0;
const char *argv[4];

argv[argc++] = "passwd";

if (is_keep)
argv[argc++] = "-k";

if (username)
argv[argc++] = username;

argv[argc] = 0;

execv (path, (char *const *) argv);
failure (errno, "execv: %s", path);
}

/* Parse a single option. */
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case 'd':
case 'k':
case 'l':
case 'u':
case 'S':
case OPT_STDIN:
if (do_fun)
{
fprintf (stderr,
"%s: options delete, keep-tokens, lock, unlock, status and stdin are mutually exclusive.\n",
program_invocation_short_name);
argp_usage (state);
}
}

switch (key)
{
case 'f':
/* do nothing */
break;
case 'd':
do_fun = do_delete;
break;
case 'k':
is_keep = 1;
do_fun = do_plain;
break;
case 'l':
do_fun = do_lock;
break;
case 'u':
do_fun = do_unlock;
break;
case 'S':
do_fun = do_status;
break;
case OPT_STDIN:
do_fun = do_stdin;
break;
case ARGP_KEY_ARG:
if (state->arg_num == 0)
/* First argument */
username = arg;
else
{
fprintf (stderr,
"%s: %s: unexpected argument.\n",
program_invocation_short_name, arg);
argp_usage (state);
}
break;

default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}

/* Our argp parser. */
static struct argp argp = {
options, parse_opt, args_doc, doc, 0, 0, 0
};

int
main (int argc, char **__restrict argv)
{
argp_parse (&argp, argc, argv, 0, 0, 0);
if (!do_fun)
do_fun = do_plain;

return do_fun ();
}
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin