|
pwconv
pwconv
/* Copyright (C) 2004 Thorsten Kukuk
Author: Thorsten Kukuk
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
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. */
#ifdef HAVE_CONFIG_H
#include
#endif
#define _GNU_SOURCE
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "public.h"
#include "logindefs.h"
#include "read-files.h"
#include "error_codes.h"
#ifndef _
#define _(String) gettext (String)
#endif
static void
print_usage (FILE *stream, const char *program)
{
fprintf (stream, _("Usage: %s\n"), program);
}
static void
print_help (const char *program)
{
print_usage (stdout, program);
fprintf (stdout, _("%s - convert to shadow account\n\n"),
program);
fputs (_(" -P path Search passwd and shadow file in \"path\"\n"),
stdout);
fputs (_(" --help Give this help list\n"), stdout);
fputs (_(" -u, --usage Give a short usage message\n"), stdout);
fputs (_(" -v, --version Print program version\n"), stdout);
}
static struct passwd *
files_getpwent (void)
{
enum nss_status status;
static int buflen = 256;
static char *buffer = NULL;
static struct passwd resultbuf;
if (buffer == NULL)
buffer = malloc (buflen);
while ((status = files_getpwent_r (&resultbuf, buffer, buflen, &errno))
== NSS_STATUS_TRYAGAIN && errno == ERANGE)
{
errno = 0;
buflen += 256;
buffer = realloc (buffer, buflen);
}
if (status == NSS_STATUS_SUCCESS)
return &resultbuf;
else
return NULL;
}
static struct spwd *
files_getspent (void)
{
enum nss_status status;
static int buflen = 256;
static char *buffer = NULL;
static struct spwd resultbuf;
if (buffer == NULL)
buffer = malloc (buflen);
while ((status = files_getspent_r (&resultbuf, buffer, buflen, &errno))
== NSS_STATUS_TRYAGAIN && errno == ERANGE)
{
errno = 0;
buflen += 256;
buffer = realloc (buffer, buflen);
}
if (status == NSS_STATUS_SUCCESS)
return &resultbuf;
else
return NULL;
}
int
main (int argc, char *argv[])
{
struct passwd *pw;
struct spwd *sp;
char *program;
char *cp;
char *tmpshadow = NULL;
char *tmppasswd = NULL;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* determine name of binary, which specifies edit mode. */
program = ((cp = strrchr (*argv, '/')) ? cp + 1 : *argv);
while (1)
{
int c;
int option_index = 0;
static struct option long_options[] = {
{"path", required_argument, NULL, 'P'},
{"version", no_argument, NULL, 'v' },
{"usage", no_argument, NULL, 'u' },
{"help", no_argument, NULL, '\255' },
{NULL, 0, NULL, '\0'}
};
c = getopt_long (argc, argv, "vuP:",
long_options, &option_index);
if (c == (-1))
break;
switch (c)
{
case 'P':
files_etc_dir = strdup (optarg);
break;
case '\255':
print_help (program);
return 0;
case 'v':
print_version (program, "2004");
return 0;
case 'u':
print_usage (stdout, program);
return 0;
default:
print_error (program);
return E_USAGE;
}
}
argc -= optind;
argv += optind;
if (argc > 0)
{
fprintf (stderr, _("%s: Too many arguments\n"), program);
print_error (program);
return E_USAGE;
}
else
{
/* Check, if /etc/shadow file exist. If not, create one. */
char *path;
struct stat st;
if (asprintf (&path, "%s/shadow", files_etc_dir) < 0)
{
fputs ("running out of memory!\n", stderr);
return E_FAILURE;
}
if (lstat (path, &st) < 0)
{
/* ENOENT means, the file does not exist and we have
to create it. Else report an error and abort. */
if (errno == ENOENT)
{
int fd = creat (path, S_IRUSR|S_IWUSR);
struct group *shadow_grp = getgrnam ("shadow");
if (fd < 0)
{
fprintf (stderr, _("Can't create %s: %m\n"), path);
return E_FAILURE;
}
close (fd);
chown (path, 0, shadow_grp ? shadow_grp->gr_gid : 0);
chmod (path, S_IRUSR|S_IWUSR|S_IRGRP);
}
else
{
fprintf (stderr, _("Can't stat %s: %m\n"), path);
return E_FAILURE;
}
}
else
{
/* else file exist, create a backup copy. */
if (asprintf (&tmpshadow, "%s/shadow.pwconv", files_etc_dir) < 0)
{
fputs ("running out of memory!\n", stderr);
return E_FAILURE;
}
link (path, tmpshadow);
}
free (path);
/* Now create a copy of the original passwd file. */
if (asprintf (&path, "%s/passwd", files_etc_dir) < 0)
{
fputs ("running out of memory!\n", stderr);
return E_FAILURE;
}
if (asprintf (&tmppasswd, "%s/passwd.pwconv", files_etc_dir) < 0)
{
fputs ("running out of memory!\n", stderr);
return E_FAILURE;
}
link (path, tmppasswd);
free (path);
}
/* Remove accounts from /etc/shadow, which have no entry in
/etc/passwd. */
while ((sp = files_getspent ()) != NULL)
{
user_t *pw_data = do_getpwnam (sp->sp_namp, NULL);
if (pw_data == NULL || pw_data->service == S_NONE)
{
user_t *sp_data = calloc (1, sizeof (user_t));
if (sp_data == NULL)
{
fputs ("running out of memory!\n", stderr);
return E_FAILURE;
}
sp_data->service = S_LOCAL;
sp_data->todo = DO_DELETE_SHADOW;
sp_data->use_shadow = 1;
sp_data->pw.pw_name = sp->sp_namp;
if (write_user_data (sp_data, 0) != 0)
{
fprintf (stderr,
_("Error while deleting `%s' shadow account.\n"),
sp_data->pw.pw_name);
free (sp_data);
return E_FAILURE;
}
free (sp_data);
}
free_user_t (pw_data);
}
/* For all accounts in /etc/passwd: If the passwd entry contains
a password and a shadow entry exist, update the shadow entry.
If no shadow entry exist, create one. */
while ((pw = files_getpwent ()) != NULL)
{
user_t *pw_data = do_getpwnam (pw->pw_name, "files");
if (pw_data == NULL || pw_data->service == S_NONE)
{
fprintf (stderr,
_("%s: Error trying to get data for `%s'\n"),
program, pw->pw_name);
return E_FAILURE;
}
/* This user does not have a shadow entry. Create one. */
if (!pw_data->use_shadow)
{
int rc;
/* Backup original password and replace it with a "x"
in local files. Report error*/
pw_data->todo = DO_MODIFY;
pw_data->sp.sp_pwdp = pw_data->pw.pw_passwd;
pw_data->newpassword = "x";
rc = write_user_data (pw_data, 0);
if (rc != 0)
{
fprintf (stderr,
_("Error while converting `%s' to shadow account.\n"),
pw_data->pw.pw_name);
free_user_t (pw_data);
return E_FAILURE;
}
pw_data->use_shadow = 1;
pw_data->todo = DO_CREATE_SHADOW;
pw_data->newpassword = strdup (pw_data->pw.pw_passwd);
pw_data->sp.sp_namp = pw_data->pw.pw_name;
pw_data->sp.sp_lstchg = time ((time_t *) 0) / (24L * 3600L);
pw_data->sp.sp_min = getlogindefs_num ("PASS_MIN_DAYS", -1);
pw_data->sp.sp_max = getlogindefs_num ("PASS_MAX_DAYS", -1);
pw_data->sp.sp_warn = getlogindefs_num ("PASS_WARN_AGE", -1);
pw_data->sp.sp_inact = -1;
pw_data->sp.sp_expire = -1;
if (write_user_data (pw_data, 0) != 0)
{
fprintf (stderr,
_("Error while converting `%s' to shadow account.\n"),
pw_data->pw.pw_name);
free_user_t (pw_data);
return E_FAILURE;
}
else
nscd_flush_cache ("passwd");
}
else if (strcmp (pw_data->pw.pw_passwd, "x") != 0)
{
/* The user has a shadow account and an entry in
/etc/passwd. */
/* Backup original password and replace it with a "x"
in local passwd file. Report error*/
int rc;
char *oldpassword = pw_data->pw.pw_passwd;
pw_data->todo = DO_MODIFY;
pw_data->newpassword = "x";
pw_data->use_shadow = 0;
rc = write_user_data (pw_data, 0);
pw_data->use_shadow = 1;
if (rc != 0)
{
fprintf (stderr,
_("Error while converting `%s' to shadow account.\n"),
pw_data->pw.pw_name);
free_user_t (pw_data);
return E_FAILURE;
}
pw_data->spn = pw_data->sp;
pw_data->spn.sp_lstchg = time ((time_t *) 0) / (24L * 3600L);
pw_data->sp_changed = 1;
pw_data->newpassword = strdup (oldpassword);
if (write_user_data (pw_data, 0) != 0)
{
fprintf (stderr,
_("Error while converting `%s' to shadow account.\n"),
pw_data->pw.pw_name);
free_user_t (pw_data);
return E_FAILURE;
}
else
nscd_flush_cache ("passwd");
}
free_user_t (pw_data);
}
/* Rename our own copy to shadow.old. As result, /etc/shadow.old
will have the contents of /etc/shadow when starting this program. */
if (tmpshadow)
{
char *oldshadow;
if (asprintf (&oldshadow, "%s/shadow.old", files_etc_dir) < 0)
{
fputs ("running out of memory!\n", stderr);
return E_FAILURE;
}
unlink (oldshadow);
rename (tmpshadow, oldshadow);
free (oldshadow);
free (tmpshadow);
}
/* Rename our own copy to passwd.old. As result, /etc/passwd.old
will have the contents of /etc/passwd when starting this program. */
if (tmppasswd)
{
char *oldpasswd;
if (asprintf (&oldpasswd, "%s/passwd.old", files_etc_dir) < 0)
{
fputs ("running out of memory!\n", stderr);
return E_FAILURE;
}
unlink (oldpasswd);
rename (tmppasswd, oldpasswd);
free (oldpasswd);
free (tmppasswd);
}
return E_SUCCESS;
}
Cheap JSP Hosting
/* Copyright (C) 2004 Thorsten Kukuk
Author: Thorsten Kukuk
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
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. */
#ifndef __PARSE_CRYPT_ARG_H__
#define __PARSE_CRYPT_ARG_H__
enum crypt_t {DES, MD5, BLOWFISH};
typedef enum crypt_t crypt_t;
extern crypt_t parse_crypt_arg (const char *arg);
extern char *make_crypt_salt (const char *crypt_prefix, int crypt_rounds);
#endif
Page:
1
2
3
4
5
6
7
8
9
10
Host JSP
JSP Hosting
JSP Web Hosting
Host JSP
|