Merge pull request #21 from fariouche/master

Add --prefix argument
This commit is contained in:
Serge Hallyn 2018-03-29 22:36:28 -07:00 committed by GitHub
commit fb356b1344
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 12139 additions and 10594 deletions

View File

@ -375,28 +375,48 @@ bool commonio_present (const struct commonio_db *db)
int commonio_lock_nowait (struct commonio_db *db, bool log) int commonio_lock_nowait (struct commonio_db *db, bool log)
{ {
char file[1024]; char* file = NULL;
char lock[1024]; char* lock = NULL;
size_t lock_file_len;
size_t file_len;
int err;
if (db->locked) { if (db->locked) {
return 1; return 1;
} }
file_len = strlen(db->filename) + 11;/* %lu max size */
snprintf (file, sizeof file, "%s.%lu", lock_file_len = strlen(db->filename) + 6; /* sizeof ".lock" */
file = (char*)malloc(file_len);
if(file == NULL) {
err = ENOMEM;
goto cleanup_ENOMEM;
}
lock = (char*)malloc(lock_file_len);
if(lock == NULL) {
err = ENOMEM;
goto cleanup_ENOMEM;
}
snprintf (file, file_len, "%s.%lu",
db->filename, (unsigned long) getpid ()); db->filename, (unsigned long) getpid ());
snprintf (lock, sizeof lock, "%s.lock", db->filename); snprintf (lock, lock_file_len, "%s.lock", db->filename);
if (do_lock_file (file, lock, log) != 0) { if (do_lock_file (file, lock, log) != 0) {
db->locked = true; db->locked = true;
lock_count++; lock_count++;
return 1; err = 1;
} }
return 0; cleanup_ENOMEM:
if(file)
free(file);
if(lock)
free(lock);
return err;
} }
int commonio_lock (struct commonio_db *db) int commonio_lock (struct commonio_db *db)
{ {
#ifdef HAVE_LCKPWDF /*#ifdef HAVE_LCKPWDF*/ /* not compatible with prefix option*/
#if 0
/* /*
* only if the system libc has a real lckpwdf() - the one from * only if the system libc has a real lckpwdf() - the one from
* lockpw.c calls us and would cause infinite recursion! * lockpw.c calls us and would cause infinite recursion!

View File

@ -155,7 +155,7 @@ static struct itemdef knowndef_table[] = {
#define LOGINDEFS "/etc/login.defs" #define LOGINDEFS "/etc/login.defs"
#endif #endif
static char def_fname[] = LOGINDEFS; /* login config defs file */ static const char* def_fname = LOGINDEFS; /* login config defs file */
static bool def_loaded = false; /* are defs already loaded? */ static bool def_loaded = false; /* are defs already loaded? */
/* local function prototypes */ /* local function prototypes */
@ -424,6 +424,17 @@ out:
return (struct itemdef *) NULL; return (struct itemdef *) NULL;
} }
/*
* setdef_config_file - set the default configuration file path
*
* must be called prior to any def* calls.
*/
void setdef_config_file (const char* file)
{
def_fname = file;
}
/* /*
* def_load - load configuration table * def_load - load configuration table
* *

View File

@ -40,6 +40,7 @@ extern unsigned long getdef_ulong (const char *, unsigned long);
extern unsigned int getdef_unum (const char *, unsigned int); extern unsigned int getdef_unum (const char *, unsigned int);
extern /*@observer@*/ /*@null@*/const char *getdef_str (const char *); extern /*@observer@*/ /*@null@*/const char *getdef_str (const char *);
extern int putdef_str (const char *, const char *); extern int putdef_str (const char *, const char *);
extern void setdef_config_file (const char* file);
/* default UMASK value if not specified in /etc/login.defs */ /* default UMASK value if not specified in /etc/login.defs */
#define GETDEF_DEFAULT_UMASK 022 #define GETDEF_DEFAULT_UMASK 022

View File

@ -274,6 +274,21 @@ extern void do_pam_passwd (const char *user, bool silent, bool change_expired);
/* port.c */ /* port.c */
extern bool isttytime (const char *, const char *, time_t); extern bool isttytime (const char *, const char *, time_t);
/* prefix_flag.c */
extern const char* process_prefix_flag (const char* short_opt, int argc, char **argv);
extern struct group *prefix_getgrnam(const char *name);
extern struct group *prefix_getgrgid(gid_t gid);
extern struct passwd *prefix_getpwuid(uid_t uid);
extern struct passwd *prefix_getpwnam(const char* name);
extern struct spwd *prefix_getspnam(const char* name);
extern struct group *prefix_getgr_nam_gid(const char *grname);
extern void prefix_setpwent();
extern struct passwd* prefix_getpwent();
extern void prefix_endpwent();
extern void prefix_setgrent();
extern struct group* prefix_getgrent();
extern void prefix_endgrent();
/* pwd2spwd.c */ /* pwd2spwd.c */
#ifndef USE_PAM #ifndef USE_PAM
extern struct spwd *pwd_to_spwd (const struct passwd *); extern struct spwd *pwd_to_spwd (const struct passwd *);

View File

@ -45,6 +45,7 @@ libmisc_a_SOURCES = \
obscure.c \ obscure.c \
pam_pass.c \ pam_pass.c \
pam_pass_non_interactive.c \ pam_pass_non_interactive.c \
prefix_flag.c \
pwd2spwd.c \ pwd2spwd.c \
pwdcheck.c \ pwdcheck.c \
pwd_init.c \ pwd_init.c \

View File

@ -136,7 +136,7 @@ static int check_gid (const gid_t gid,
} }
/* Check if the GID exists according to NSS */ /* Check if the GID exists according to NSS */
errno = 0; errno = 0;
if (getgrgid (gid) != NULL) { if (prefix_getgrgid (gid) != NULL) {
return EEXIST; return EEXIST;
} else { } else {
/* getgrgid() was NULL /* getgrgid() was NULL

View File

@ -136,7 +136,7 @@ static int check_uid(const uid_t uid,
} }
/* Check if the UID exists according to NSS */ /* Check if the UID exists according to NSS */
errno = 0; errno = 0;
if (getpwuid(uid) != NULL) { if (prefix_getpwuid(uid) != NULL) {
return EEXIST; return EEXIST;
} else { } else {
/* getpwuid() was NULL /* getpwuid() was NULL

340
libmisc/prefix_flag.c Normal file
View File

@ -0,0 +1,340 @@
/*
* Copyright (c) 2011 , Julian Pidancet
* Copyright (c) 2011 , Nicolas François
* 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. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
* HOLDERS 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.
*/
#include <config.h>
#ident "$Id$"
#include <stdio.h>
#include <assert.h>
#include "defines.h"
#include "prototypes.h"
/*@-exitarg@*/
#include "exitcodes.h"
#include "groupio.h"
#include "pwio.h"
#ifdef SHADOWGRP
#include "sgroupio.h"
#endif
#include "shadowio.h"
#ifdef ENABLE_SUBIDS
#include "subordinateio.h"
#endif /* ENABLE_SUBIDS */
#include "getdef.h"
static char *passwd_db_file = NULL;
static char *spw_db_file = NULL;
static char *group_db_file = NULL;
static char *sgroup_db_file = NULL;
static char *suid_db_file = NULL;
static char *sgid_db_file = NULL;
static char *def_conf_file = NULL;
static FILE* fp_pwent = NULL;
static FILE* fp_grent = NULL;
/*
* process_prefix_flag - prefix all paths if given the --prefix option
*
* This shall be called before accessing the passwd, group, shadow,
* gshadow, useradd's default, login.defs files (non exhaustive list)
* or authenticating the caller.
*
* The audit, syslog, or locale files shall be open before
*/
extern const char* process_prefix_flag (const char* short_opt, int argc, char **argv)
{
/*
* Parse the command line options.
*/
int i;
const char *prefix = NULL;
for (i = 0; i < argc; i++) {
if ( (strcmp (argv[i], "--prefix") == 0)
|| (strcmp (argv[i], short_opt) == 0)) {
if (NULL != prefix) {
fprintf (stderr,
_("%s: multiple --prefix options\n"),
Prog);
exit (E_BAD_ARG);
}
if (i + 1 == argc) {
fprintf (stderr,
_("%s: option '%s' requires an argument\n"),
Prog, argv[i]);
exit (E_BAD_ARG);
}
prefix = argv[i + 1];
}
}
if (prefix != NULL) {
if ( prefix[0] == '\0' || !strcmp(prefix, "/"))
return ""; /* if prefix is "/" then we ignore the flag option */
/* should we prevent symbolic link from being used as a prefix? */
size_t len;
len = strlen(prefix) + strlen(PASSWD_FILE) + 2;
passwd_db_file = xmalloc(len);
snprintf(passwd_db_file, len, "%s/%s", prefix, PASSWD_FILE);
pw_setdbname(passwd_db_file);
len = strlen(prefix) + strlen(GROUP_FILE) + 2;
group_db_file = xmalloc(len);
snprintf(group_db_file, len, "%s/%s", prefix, GROUP_FILE);
gr_setdbname(group_db_file);
#ifdef SHADOWGRP
len = strlen(prefix) + strlen(SGROUP_FILE) + 2;
sgroup_db_file = xmalloc(len);
snprintf(sgroup_db_file, len, "%s/%s", prefix, SGROUP_FILE);
sgr_setdbname(sgroup_db_file);
#endif
#ifdef USE_NIS
__setspNIS(0); /* disable NIS for now, at least until it is properly supporting a "prefix" */
#endif
len = strlen(prefix) + strlen(SHADOW_FILE) + 2;
spw_db_file = xmalloc(len);
snprintf(spw_db_file, len, "%s/%s", prefix, SHADOW_FILE);
spw_setdbname(spw_db_file);
len = strlen(prefix) + strlen("/etc/subuid") + 2;
suid_db_file = xmalloc(len);
snprintf(suid_db_file, len, "%s/%s", prefix, "/etc/subuid");
sub_uid_setdbname(suid_db_file);
len = strlen(prefix) + strlen("/etc/subgid") + 2;
sgid_db_file = xmalloc(len);
snprintf(sgid_db_file, len, "%s/%s", prefix, "/etc/subgid");
sub_gid_setdbname(sgid_db_file);
len = strlen(prefix) + strlen("/etc/login.defs") + 2;
def_conf_file = xmalloc(len);
snprintf(def_conf_file, len, "%s/%s", prefix, "/etc/login.defs");
setdef_config_file(def_conf_file);
}
if (prefix == NULL)
return "";
return prefix;
}
extern struct group *prefix_getgrnam(const char *name)
{
if (group_db_file) {
FILE* fg;
struct group * grp = NULL;
fg = fopen(group_db_file, "rt");
if(!fg)
return NULL;
while(grp = fgetgrent(fg)) {
if(!strcmp(name, grp->gr_name))
break;
}
fclose(fg);
return grp;
}
return getgrnam(name);
}
extern struct group *prefix_getgrgid(gid_t gid)
{
if (group_db_file) {
FILE* fg;
struct group * grp = NULL;
fg = fopen(group_db_file, "rt");
if(!fg)
return NULL;
while(grp = fgetgrent(fg)) {
if(gid == grp->gr_gid)
break;
}
fclose(fg);
return grp;
}
return getgrgid(gid);
}
extern struct passwd *prefix_getpwuid(uid_t uid)
{
if (passwd_db_file) {
FILE* fg;
struct passwd *pwd = NULL;
fg = fopen(passwd_db_file, "rt");
if(!fg)
return NULL;
while(pwd = fgetpwent(fg)) {
if(uid == pwd->pw_uid)
break;
}
fclose(fg);
return pwd;
}
else {
return getpwuid(uid);
}
}
extern struct passwd *prefix_getpwnam(const char* name)
{
if (passwd_db_file) {
FILE* fg;
struct passwd *pwd = NULL;
fg = fopen(passwd_db_file, "rt");
if(!fg)
return NULL;
while(pwd = fgetpwent(fg)) {
if(!strcmp(name, pwd->pw_name))
break;
}
fclose(fg);
return pwd;
}
else {
return getpwnam(name);
}
}
extern struct spwd *prefix_getspnam(const char* name)
{
if (spw_db_file) {
FILE* fg;
struct spwd *sp = NULL;
fg = fopen(spw_db_file, "rt");
if(!fg)
return NULL;
while(sp = fgetspent(fg)) {
if(!strcmp(name, sp->sp_namp))
break;
}
fclose(fg);
return sp;
}
else {
return getspnam(name);
}
}
extern void prefix_setpwent()
{
if(!passwd_db_file) {
setpwent();
return;
}
if (fp_pwent)
fclose (fp_pwent);
fp_pwent = fopen(passwd_db_file, "rt");
if(!fp_pwent)
return;
}
extern struct passwd* prefix_getpwent()
{
if(!passwd_db_file) {
return getpwent();
}
return fgetpwent(fp_pwent);
}
extern void prefix_endpwent()
{
if(!passwd_db_file) {
endpwent();
return;
}
if (fp_pwent)
fclose(fp_pwent);
fp_pwent = NULL;
}
extern void prefix_setgrent()
{
if(!group_db_file) {
setgrent();
return;
}
if (fp_grent)
fclose (fp_grent);
fp_grent = fopen(group_db_file, "rt");
if(!fp_grent)
return;
}
extern struct group* prefix_getgrent()
{
if(!group_db_file) {
return getgrent();
}
return fgetgrent(fp_grent);
}
extern void prefix_endgrent()
{
if(!group_db_file) {
endgrent();
return;
}
if (fp_grent)
fclose(fp_grent);
fp_grent = NULL;
}
extern struct group *prefix_getgr_nam_gid(const char *grname)
{
long long int gid;
char *endptr;
if (NULL == grname) {
return NULL;
}
if (group_db_file) {
errno = 0;
gid = strtoll (grname, &endptr, 10);
if ( ('\0' != *grname)
&& ('\0' == *endptr)
&& (ERANGE != errno)
&& (gid == (gid_t)gid)) {
return prefix_getgrgid ((gid_t) gid);
}
return prefix_getgrnam (grname);
}
else
return getgr_nam_gid(grname);
}

View File

@ -212,6 +212,23 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<option>-P</option>, <option>--prefix</option>&nbsp;<replaceable>PREFIX_DIR</replaceable>
</term>
<listitem>
<para>
Apply changes in the <replaceable>PREFIX_DIR</replaceable>
directory and use the configuration files from the
<replaceable>PREFIX_DIR</replaceable> directory.
This option does not chroot and is intended for preparing
a cross-compilation target.
Some limitations: NIS and LDAP users/groups are not verified.
PAM authentication is using the host files.
No SELINUX support.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>

View File

@ -109,6 +109,23 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<option>-P</option>, <option>--prefix</option>&nbsp;<replaceable>PREFIX_DIR</replaceable>
</term>
<listitem>
<para>
Apply changes in the <replaceable>PREFIX_DIR</replaceable>
directory and use the configuration files from the
<replaceable>PREFIX_DIR</replaceable> directory.
This option does not chroot and is intended for preparing
a cross-compilation target.
Some limitations: NIS and LDAP users/groups are not verified.
PAM authentication is using the host files.
No SELINUX support.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>

View File

@ -186,6 +186,23 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<option>-P</option>, <option>--prefix</option>&nbsp;<replaceable>PREFIX_DIR</replaceable>
</term>
<listitem>
<para>
Apply changes in the <replaceable>PREFIX_DIR</replaceable>
directory and use the configuration files from the
<replaceable>PREFIX_DIR</replaceable> directory.
This option does not chroot and is intended for preparing
a cross-compilation target.
Some limitations: NIS and LDAP users/groups are not verified.
PAM authentication is using the host files.
No SELINUX support.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>
@ -278,16 +295,19 @@
<para>E_GRP_UPDATE: can't update group file</para> <para>E_GRP_UPDATE: can't update group file</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><replaceable>11</replaceable></term> <term><replaceable>11</replaceable></term>
<listitem> <listitem>
<para>E_CLEANUP_SERVICE: can't setup cleanup service</para> <para>E_CLEANUP_SERVICE: can't setup cleanup service</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><replaceable>12</replaceable></term> <term><replaceable>12</replaceable></term>
<listitem> <listitem>
<para>E_PAM_USERNAME: can't determine your username for use with pam</para> <para>E_PAM_USERNAME: can't determine your username for use with pam</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><replaceable>13</replaceable></term> <term><replaceable>13</replaceable></term>
<listitem> <listitem>
<para>E_PAM_ERROR: pam returned an error, see syslog facility id groupmod for the PAM error message</para> <para>E_PAM_ERROR: pam returned an error, see syslog facility id groupmod for the PAM error message</para>

View File

@ -453,6 +453,23 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<option>-P</option>, <option>--prefix</option>&nbsp;<replaceable>PREFIX_DIR</replaceable>
</term>
<listitem>
<para>
Apply changes in the <replaceable>PREFIX_DIR</replaceable>
directory and use the configuration files from the
<replaceable>PREFIX_DIR</replaceable> directory.
This option does not chroot and is intended for preparing
a cross-compilation target.
Some limitations: NIS and LDAP users/groups are not verified.
PAM authentication is using the host files.
No SELINUX support.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<option>-s</option>, <option>--shell</option>&nbsp;<replaceable>SHELL</replaceable> <option>-s</option>, <option>--shell</option>&nbsp;<replaceable>SHELL</replaceable>

View File

@ -154,6 +154,23 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<option>-P</option>, <option>--prefix</option>&nbsp;<replaceable>PREFIX_DIR</replaceable>
</term>
<listitem>
<para>
Apply changes in the <replaceable>PREFIX_DIR</replaceable>
directory and use the configuration files from the
<replaceable>PREFIX_DIR</replaceable> directory.
This option does not chroot and is intended for preparing
a cross-compilation target.
Some limitations: NIS and LDAP users/groups are not verified.
PAM authentication is using the host files.
No SELINUX support.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<option>-Z</option>, <option>--selinux-user</option> <option>-Z</option>, <option>--selinux-user</option>

View File

@ -319,6 +319,23 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<option>-P</option>, <option>--prefix</option>&nbsp;<replaceable>PREFIX_DIR</replaceable>
</term>
<listitem>
<para>
Apply changes in the <replaceable>PREFIX_DIR</replaceable>
directory and use the configuration files from the
<replaceable>PREFIX_DIR</replaceable> directory.
This option does not chroot and is intended for preparing
a cross-compilation target.
Some limitations: NIS and LDAP users/groups are not verified.
PAM authentication is using the host files.
No SELINUX support.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<option>-s</option>, <option>--shell</option>&nbsp;<replaceable>SHELL</replaceable> <option>-s</option>, <option>--shell</option>&nbsp;<replaceable>SHELL</replaceable>

302
po/cs.po
View File

@ -6,7 +6,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: shadow 4.2\n" "Project-Id-Version: shadow 4.2\n"
"Report-Msgid-Bugs-To: pkg-shadow-devel@lists.alioth.debian.org\n" "Report-Msgid-Bugs-To: pkg-shadow-devel@lists.alioth.debian.org\n"
"POT-Creation-Date: 2014-08-22 17:05+0200\n" "POT-Creation-Date: 2016-09-18 14:03-0500\n"
"PO-Revision-Date: 2014-08-24 15:07+0200\n" "PO-Revision-Date: 2014-08-24 15:07+0200\n"
"Last-Translator: Miroslav Kure <kurem@debian.cz>\n" "Last-Translator: Miroslav Kure <kurem@debian.cz>\n"
"Language-Team: Czech <debian-l10n-czech@lists.debian.org>\n" "Language-Team: Czech <debian-l10n-czech@lists.debian.org>\n"
@ -330,30 +330,6 @@ msgstr "%s: Nelze získat jedinečné systémové GID (volná GID neexistují)\n
msgid "%s: Can't get unique GID (no more available GIDs)\n" msgid "%s: Can't get unique GID (no more available GIDs)\n"
msgstr "%s: Nelze získat jedinečné GID (volná GID neexistují)\n" msgstr "%s: Nelze získat jedinečné GID (volná GID neexistují)\n"
#, c-format
msgid ""
"%s: Invalid configuration: SUB_GID_MIN (%lu), SUB_GID_MAX (%lu), "
"SUB_GID_COUNT (%lu)\n"
msgstr ""
"%s: Neplatné nastavení: SUB_GID_MIN (%lu), SUB_GID_MAX (%lu), "
"SUB_GID_COUNT (%lu)\n"
#, c-format
msgid "%s: Can't get unique subordinate GID range\n"
msgstr "%s: Nelze získat jedinečný rozsah podřízených GID\n"
#, c-format
msgid ""
"%s: Invalid configuration: SUB_UID_MIN (%lu), SUB_UID_MAX (%lu), "
"SUB_UID_COUNT (%lu)\n"
msgstr ""
"%s: Neplatné nastavení: SUB_UID_MIN (%lu), SUB_UID_MAX (%lu), "
"SUB_UID_COUNT (%lu)\n"
#, c-format
msgid "%s: Can't get unique subordinate UID range\n"
msgstr "%s: Nelze získat jedinečný rozsah podřízených UID\n"
#, c-format #, c-format
msgid "%s: Invalid configuration: UID_MIN (%lu), UID_MAX (%lu)\n" msgid "%s: Invalid configuration: UID_MIN (%lu), UID_MAX (%lu)\n"
msgstr "%s: Neplatné nastavení: UID_MIN (%lu), UID_MAX (%lu)\n" msgstr "%s: Neplatné nastavení: UID_MIN (%lu), UID_MAX (%lu)\n"
@ -373,26 +349,6 @@ msgstr "%s: Nelze získat jedinečné systémové UID (volná UID neexistují)\n
msgid "%s: Can't get unique UID (no more available UIDs)\n" msgid "%s: Can't get unique UID (no more available UIDs)\n"
msgstr "%s: Nelze získat jedinečné UID (volná UID neexistují)\n" msgstr "%s: Nelze získat jedinečné UID (volná UID neexistují)\n"
#, c-format
msgid "%s: Not enough arguments to form %u mappings\n"
msgstr "%s: Nedostatek argumentů pro vytvoření %u mapování\n"
#, c-format
msgid "%s: Memory allocation failure\n"
msgstr "%s: Chyba alokace paměti\n"
#, c-format
msgid "%s: snprintf failed!\n"
msgstr "%s: snprintf selhalo!\n"
#, c-format
msgid "%s: open of %s failed: %s\n"
msgstr "%s: otevření %s selhalo: %s\n"
#, c-format
msgid "%s: write to %s failed: %s\n"
msgstr "%s: zápis do %s selhal: %s\n"
msgid "Too many logins.\n" msgid "Too many logins.\n"
msgstr "Příliš mnoho přihlášení.\n" msgstr "Příliš mnoho přihlášení.\n"
@ -444,27 +400,6 @@ msgstr "passwd: heslo nebylo změněno\n"
msgid "passwd: password updated successfully\n" msgid "passwd: password updated successfully\n"
msgstr "passwd: heslo bylo úspěšně změněno\n" msgstr "passwd: heslo bylo úspěšně změněno\n"
#, c-format
msgid "%s: PAM modules requesting echoing are not supported.\n"
msgstr ""
"%s: PAM moduly vyžadující zobrazování zpětné vazby nejsou podporovány.\n"
#, c-format
msgid "%s: conversation type %d not supported.\n"
msgstr "%s: typ konverzace %d není podporován.\n"
#, c-format
msgid "%s: (user %s) pam_start failure %d\n"
msgstr "%s: (uživatel %s) chyba pam_start %d\n"
#, c-format
msgid ""
"%s: (user %s) pam_chauthtok() failed, error:\n"
"%s\n"
msgstr ""
"%s: (uživatel %s) volání pam_chauthtok() selhalo, chyba:\n"
"%s\n"
#, c-format #, c-format
msgid "Incorrect password for %s.\n" msgid "Incorrect password for %s.\n"
msgstr "Chybné heslo pro %s.\n" msgstr "Chybné heslo pro %s.\n"
@ -524,14 +459,6 @@ msgstr "Chybný kořenový adresář „%s“\n"
msgid "Can't change root directory to '%s'\n" msgid "Can't change root directory to '%s'\n"
msgstr "Nelze změnit kořenový adresář na „%s“\n" msgstr "Nelze změnit kořenový adresář na „%s“\n"
#, c-format
msgid "%s: user %s is currently logged in\n"
msgstr "%s: uživatel %s je právě přihlášen\n"
#, c-format
msgid "%s: user %s is currently used by process %d\n"
msgstr "%s: uživatel %s je momentálně používán procesem %d\n"
msgid "Unable to determine your tty name." msgid "Unable to determine your tty name."
msgstr "Nelze zjistit vaše uživatelské jméno." msgstr "Nelze zjistit vaše uživatelské jméno."
@ -1158,6 +1085,15 @@ msgstr "%s: GID „%lu“ již existuje\n"
msgid "%s: Cannot setup cleanup service.\n" msgid "%s: Cannot setup cleanup service.\n"
msgstr "%s: nelze nastavit úklidovou službu.\n" msgstr "%s: nelze nastavit úklidovou službu.\n"
#, fuzzy
#| msgid ""
#| " -r, --reset reset the counters of login failures\n"
msgid ""
" -f, --force delete group even if it is the primary group "
"of a user\n"
msgstr ""
" -r, --reset vynuluje počitadla chybných přihlášení\n"
#, c-format #, c-format
msgid "%s: cannot remove entry '%s' from %s\n" msgid "%s: cannot remove entry '%s' from %s\n"
msgstr "%s: nelze odstranit záznam „%s“ z %s\n" msgstr "%s: nelze odstranit záznam „%s“ z %s\n"
@ -1383,6 +1319,26 @@ msgid ""
msgstr "" msgstr ""
" -b, --before DNŮ zobrazí záznamy lastlogu starší než DNŮ\n" " -b, --before DNŮ zobrazí záznamy lastlogu starší než DNŮ\n"
#, fuzzy
#| msgid ""
#| " -a, --all display faillog records for all users\n"
msgid ""
" -C, --clear clear lastlog record of an user (usable only "
"with -u)\n"
msgstr ""
" -a, --all zobrazí záznamy faillogu o všech "
"uživatelích\n"
#, fuzzy
#| msgid ""
#| " -a, --all display faillog records for all users\n"
msgid ""
" -S, --set set lastlog record to current time (usable "
"only with -u)\n"
msgstr ""
" -a, --all zobrazí záznamy faillogu o všech "
"uživatelích\n"
msgid "" msgid ""
" -t, --time DAYS print only lastlog records more recent than " " -t, --time DAYS print only lastlog records more recent than "
"DAYS\n" "DAYS\n"
@ -1403,6 +1359,24 @@ msgstr "Uživatel Port Naposledy"
msgid "**Never logged in**" msgid "**Never logged in**"
msgstr "**Nikdy nebyl přihlášen**" msgstr "**Nikdy nebyl přihlášen**"
#, fuzzy, c-format
#| msgid "%s: Failed to get the entry for UID %lu\n"
msgid "%s: Failed to update the entry for UID %lu\n"
msgstr "%s: nepodařilo se získat záznam pro UID %lu\n"
#, fuzzy, c-format
#| msgid "%s: can't update password file\n"
msgid "%s: Failed to update the lastlog file\n"
msgstr "%s: soubor s hesly nelze aktualizovat\n"
#, c-format
msgid "%s: Option -C cannot be used together with option -S\n"
msgstr ""
#, c-format
msgid "%s: Options -C and -S require option -u to specify the user\n"
msgstr ""
#, c-format #, c-format
msgid "Usage: %s [-p] [name]\n" msgid "Usage: %s [-p] [name]\n"
msgstr "Použití: %s [-p] [jméno]\n" msgstr "Použití: %s [-p] [jméno]\n"
@ -1436,6 +1410,13 @@ msgstr ""
"\n" "\n"
"[Odpojení přeskočeno -- uživatel root smí být přihlášen.]" "[Odpojení přeskočeno -- uživatel root smí být přihlášen.]"
#, c-format
msgid "%s: Cannot possibly work without effective root\n"
msgstr "%s: Bez efektivních oprávnění uživatele root nelze pracovat\n"
msgid "No utmp entry. You must exec \"login\" from the lowest level \"sh\""
msgstr "utmp záznam neexistuje. Musíte spustit „login“ z nejnižšího „sh“"
#, c-format #, c-format
msgid "" msgid ""
"\n" "\n"
@ -1444,13 +1425,6 @@ msgstr ""
"\n" "\n"
"Vypršel časový limit pro přihlášení (%u sekund).\n" "Vypršel časový limit pro přihlášení (%u sekund).\n"
#, c-format
msgid "%s: Cannot possibly work without effective root\n"
msgstr "%s: Bez efektivních oprávnění uživatele root nelze pracovat\n"
msgid "No utmp entry. You must exec \"login\" from the lowest level \"sh\""
msgstr "utmp záznam neexistuje. Musíte spustit „login“ z nejnižšího „sh“"
#, c-format #, c-format
msgid "login: PAM Failure, aborting: %s\n" msgid "login: PAM Failure, aborting: %s\n"
msgstr "login: Chyba PAM, končím: %s\n" msgstr "login: Chyba PAM, končím: %s\n"
@ -1517,28 +1491,6 @@ msgstr ""
msgid "Usage: logoutd\n" msgid "Usage: logoutd\n"
msgstr "Použití: logoutd\n" msgstr "Použití: logoutd\n"
#, c-format
msgid "%s: gid range [%lu-%lu) -> [%lu-%lu) not allowed\n"
msgstr "%s: rozsah gid [%lu-%lu) -> [%lu-%lu) není povolen\n"
#, c-format
msgid ""
"usage: %s <pid> <gid> <lowergid> <count> [ <gid> <lowergid> <count> ] ... \n"
msgstr ""
"použití: %s <pid> <gid> <spodnígid> <počet> [ <gid> <spodnígid> <počet> ] ...\n"
#, c-format
msgid "%s: Could not open proc directory for target %u\n"
msgstr "%s: Nelze otevřít proc adresář cílového procesu %u\n"
#, c-format
msgid "%s: Could not stat directory for target %u\n"
msgstr "%s: Nelze zavolat stat na adresář cílového procesu %u\n"
#, c-format
msgid "%s: Target %u is owned by a different user\n"
msgstr "%s: Cílový proces %u je vlastněn jiným uživatelem\n"
msgid "Usage: newgrp [-] [group]\n" msgid "Usage: newgrp [-] [group]\n"
msgstr "Použití: newgrp [-] [skupina]\n" msgstr "Použití: newgrp [-] [skupina]\n"
@ -1563,16 +1515,6 @@ msgstr "%s: GID „%lu“ neexistuje\n"
msgid "too many groups\n" msgid "too many groups\n"
msgstr "příliš mnoho skupin\n" msgstr "příliš mnoho skupin\n"
#, c-format
msgid "%s: uid range [%lu-%lu) -> [%lu-%lu) not allowed\n"
msgstr "%s: rozsah uid [%lu-%lu) -> [%lu-%lu) není povolen\n"
#, c-format
msgid ""
"usage: %s <pid> <uid> <loweruid> <count> [ <uid> <loweruid> <count> ] ... \n"
msgstr ""
"použití: %s <pid> <uid> <spodníuid> <počet> [ <uid> <spodníuid> <počet> ] ...\n"
msgid " -r, --system create system accounts\n" msgid " -r, --system create system accounts\n"
msgstr " -r, --system vytvoří systémový účet\n" msgstr " -r, --system vytvoří systémový účet\n"
@ -1898,12 +1840,6 @@ msgstr "Ověřování heslem vynecháno.\n"
msgid "Please enter your OWN password as authentication.\n" msgid "Please enter your OWN password as authentication.\n"
msgstr "Pro ověření zadejte VAŠE vlastní heslo.\n" msgstr "Pro ověření zadejte VAŠE vlastní heslo.\n"
msgid " ...killed.\n"
msgstr " ...zabit.\n"
msgid " ...waiting for child to terminate.\n"
msgstr " ...čeká na ukončení potomka.\n"
#, c-format #, c-format
msgid "%s: Cannot fork user shell\n" msgid "%s: Cannot fork user shell\n"
msgstr "%s: Nelze rozdvojit uživatelský shell\n" msgstr "%s: Nelze rozdvojit uživatelský shell\n"
@ -1919,6 +1855,12 @@ msgstr "%s: chyba maskování signálu\n"
msgid "Session terminated, terminating shell..." msgid "Session terminated, terminating shell..."
msgstr "Sezení skončeno, ukončuji shell..." msgstr "Sezení skončeno, ukončuji shell..."
msgid " ...killed.\n"
msgstr " ...zabit.\n"
msgid " ...waiting for child to terminate.\n"
msgstr " ...čeká na ukončení potomka.\n"
msgid " ...terminated.\n" msgid " ...terminated.\n"
msgstr " ...ukončen.\n" msgstr " ...ukončen.\n"
@ -2486,22 +2428,6 @@ msgstr "%s: UID „%lu“ již existuje\n"
msgid "%s: %s does not exist, you cannot use the flags %s or %s\n" msgid "%s: %s does not exist, you cannot use the flags %s or %s\n"
msgstr "%s: %s neexistuje, nemůžete použít přepínač %s ani %s\n" msgstr "%s: %s neexistuje, nemůžete použít přepínač %s ani %s\n"
#, c-format
msgid "%s: failed to remove uid range %lu-%lu from '%s'\n"
msgstr "%s: odebrání rozsahu uid %lu-%lu z „%s“ selhalo\n"
#, c-format
msgid "%s: failed to add uid range %lu-%lu from '%s'\n"
msgstr "%s: přidání rozsahu uid %lu-%lu z „%s“ selhalo\n"
#, c-format
msgid "%s: failed to remove gid range %lu-%lu from '%s'\n"
msgstr "%s: odebrání rozsahu gid %lu-%lu z „%s“ selhalo\n"
#, c-format
msgid "%s: failed to add gid range %lu-%lu from '%s'\n"
msgstr "%s: přidání rozsahu gid %lu-%lu z „%s“ selhalo\n"
#, c-format #, c-format
msgid "%s: directory %s exists\n" msgid "%s: directory %s exists\n"
msgstr "%s: adresář %s již existuje\n" msgstr "%s: adresář %s již existuje\n"
@ -2548,6 +2474,22 @@ msgstr "chyba při změně vlastníka poštovní schránky"
msgid "failed to rename mailbox" msgid "failed to rename mailbox"
msgstr "chyba při přejmenovávání poštovní schránky" msgstr "chyba při přejmenovávání poštovní schránky"
#, c-format
msgid "%s: failed to remove uid range %lu-%lu from '%s'\n"
msgstr "%s: odebrání rozsahu uid %lu-%lu z „%s“ selhalo\n"
#, c-format
msgid "%s: failed to add uid range %lu-%lu from '%s'\n"
msgstr "%s: přidání rozsahu uid %lu-%lu z „%s“ selhalo\n"
#, c-format
msgid "%s: failed to remove gid range %lu-%lu from '%s'\n"
msgstr "%s: odebrání rozsahu gid %lu-%lu z „%s“ selhalo\n"
#, c-format
msgid "%s: failed to add gid range %lu-%lu from '%s'\n"
msgstr "%s: přidání rozsahu gid %lu-%lu z „%s“ selhalo\n"
#, c-format #, c-format
msgid "" msgid ""
"You have modified %s.\n" "You have modified %s.\n"
@ -2634,6 +2576,93 @@ msgstr "%s: %s nelze obnovit: %s (změny jsou v %s)\n"
msgid "%s: failed to find tcb directory for %s\n" msgid "%s: failed to find tcb directory for %s\n"
msgstr "%s: nepodařilo se nalézt tcb adresář uživatele %s\n" msgstr "%s: nepodařilo se nalézt tcb adresář uživatele %s\n"
#~ msgid ""
#~ "%s: Invalid configuration: SUB_GID_MIN (%lu), SUB_GID_MAX (%lu), "
#~ "SUB_GID_COUNT (%lu)\n"
#~ msgstr ""
#~ "%s: Neplatné nastavení: SUB_GID_MIN (%lu), SUB_GID_MAX (%lu), "
#~ "SUB_GID_COUNT (%lu)\n"
#~ msgid "%s: Can't get unique subordinate GID range\n"
#~ msgstr "%s: Nelze získat jedinečný rozsah podřízených GID\n"
#~ msgid ""
#~ "%s: Invalid configuration: SUB_UID_MIN (%lu), SUB_UID_MAX (%lu), "
#~ "SUB_UID_COUNT (%lu)\n"
#~ msgstr ""
#~ "%s: Neplatné nastavení: SUB_UID_MIN (%lu), SUB_UID_MAX (%lu), "
#~ "SUB_UID_COUNT (%lu)\n"
#~ msgid "%s: Can't get unique subordinate UID range\n"
#~ msgstr "%s: Nelze získat jedinečný rozsah podřízených UID\n"
#~ msgid "%s: Not enough arguments to form %u mappings\n"
#~ msgstr "%s: Nedostatek argumentů pro vytvoření %u mapování\n"
#~ msgid "%s: Memory allocation failure\n"
#~ msgstr "%s: Chyba alokace paměti\n"
#~ msgid "%s: snprintf failed!\n"
#~ msgstr "%s: snprintf selhalo!\n"
#~ msgid "%s: open of %s failed: %s\n"
#~ msgstr "%s: otevření %s selhalo: %s\n"
#~ msgid "%s: write to %s failed: %s\n"
#~ msgstr "%s: zápis do %s selhal: %s\n"
#~ msgid "%s: PAM modules requesting echoing are not supported.\n"
#~ msgstr ""
#~ "%s: PAM moduly vyžadující zobrazování zpětné vazby nejsou podporovány.\n"
#~ msgid "%s: conversation type %d not supported.\n"
#~ msgstr "%s: typ konverzace %d není podporován.\n"
#~ msgid "%s: (user %s) pam_start failure %d\n"
#~ msgstr "%s: (uživatel %s) chyba pam_start %d\n"
#~ msgid ""
#~ "%s: (user %s) pam_chauthtok() failed, error:\n"
#~ "%s\n"
#~ msgstr ""
#~ "%s: (uživatel %s) volání pam_chauthtok() selhalo, chyba:\n"
#~ "%s\n"
#~ msgid "%s: user %s is currently logged in\n"
#~ msgstr "%s: uživatel %s je právě přihlášen\n"
#~ msgid "%s: user %s is currently used by process %d\n"
#~ msgstr "%s: uživatel %s je momentálně používán procesem %d\n"
#~ msgid "%s: gid range [%lu-%lu) -> [%lu-%lu) not allowed\n"
#~ msgstr "%s: rozsah gid [%lu-%lu) -> [%lu-%lu) není povolen\n"
#~ msgid ""
#~ "usage: %s <pid> <gid> <lowergid> <count> [ <gid> <lowergid> "
#~ "<count> ] ... \n"
#~ msgstr ""
#~ "použití: %s <pid> <gid> <spodnígid> <počet> [ <gid> <spodnígid> "
#~ "<počet> ] ...\n"
#~ msgid "%s: Could not open proc directory for target %u\n"
#~ msgstr "%s: Nelze otevřít proc adresář cílového procesu %u\n"
#~ msgid "%s: Could not stat directory for target %u\n"
#~ msgstr "%s: Nelze zavolat stat na adresář cílového procesu %u\n"
#~ msgid "%s: Target %u is owned by a different user\n"
#~ msgstr "%s: Cílový proces %u je vlastněn jiným uživatelem\n"
#~ msgid "%s: uid range [%lu-%lu) -> [%lu-%lu) not allowed\n"
#~ msgstr "%s: rozsah uid [%lu-%lu) -> [%lu-%lu) není povolen\n"
#~ msgid ""
#~ "usage: %s <pid> <uid> <loweruid> <count> [ <uid> <loweruid> "
#~ "<count> ] ... \n"
#~ msgstr ""
#~ "použití: %s <pid> <uid> <spodníuid> <počet> [ <uid> <spodníuid> "
#~ "<počet> ] ...\n"
#~ msgid " -c, --crypt-method the crypt method (one of %s)\n" #~ msgid " -c, --crypt-method the crypt method (one of %s)\n"
#~ msgstr " -c, --crypt-method typ šifry (jeden z %s)\n" #~ msgstr " -c, --crypt-method typ šifry (jeden z %s)\n"
@ -3270,9 +3299,6 @@ msgstr "%s: nepodařilo se nalézt tcb adresář uživatele %s\n"
#~ msgid "%s: can't rewrite password file\n" #~ msgid "%s: can't rewrite password file\n"
#~ msgstr "%s: soubor s hesly nelze přepsat\n" #~ msgstr "%s: soubor s hesly nelze přepsat\n"
#~ msgid "%s: can't update password file\n"
#~ msgstr "%s: soubor s hesly nelze aktualizovat\n"
#~ msgid "%s: can't update shadow password file\n" #~ msgid "%s: can't update shadow password file\n"
#~ msgstr "%s: soubor se stínovými hesly nelze aktualizovat\n" #~ msgstr "%s: soubor se stínovými hesly nelze aktualizovat\n"

196
po/de.po
View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: shadow 4.2-2\n" "Project-Id-Version: shadow 4.2-2\n"
"Report-Msgid-Bugs-To: pkg-shadow-devel@lists.alioth.debian.org\n" "Report-Msgid-Bugs-To: pkg-shadow-devel@lists.alioth.debian.org\n"
"POT-Creation-Date: 2012-05-20 19:52+0200\n" "POT-Creation-Date: 2016-09-18 14:03-0500\n"
"PO-Revision-Date: 2014-07-27 23:06+0200\n" "PO-Revision-Date: 2014-07-27 23:06+0200\n"
"Last-Translator: Holger Wansing <hwansing@mailbox.org>\n" "Last-Translator: Holger Wansing <hwansing@mailbox.org>\n"
"Language-Team: German <debian-l10n-german@lists.debian.org>\n" "Language-Team: German <debian-l10n-german@lists.debian.org>\n"
@ -428,6 +428,11 @@ msgstr "%s: Ungültiger chroot-Pfad »%s«\n"
msgid "%s: cannot access chroot directory %s: %s\n" msgid "%s: cannot access chroot directory %s: %s\n"
msgstr "%s: auf chroot-Verzeichnis %s kann nicht zugegriffen werden: %s\n" msgstr "%s: auf chroot-Verzeichnis %s kann nicht zugegriffen werden: %s\n"
#, fuzzy, c-format
#| msgid "%s: cannot access chroot directory %s: %s\n"
msgid "%s: cannot chdir to chroot directory %s: %s\n"
msgstr "%s: auf chroot-Verzeichnis %s kann nicht zugegriffen werden: %s\n"
#, c-format #, c-format
msgid "%s: unable to chroot to directory %s: %s\n" msgid "%s: unable to chroot to directory %s: %s\n"
msgstr "%s: chroot-Wechsel in Verzeichnis %s nicht möglich: %s\n" msgstr "%s: chroot-Wechsel in Verzeichnis %s nicht möglich: %s\n"
@ -796,6 +801,11 @@ msgstr "%s: Zeile %d: Zeile zu lang\n"
msgid "%s: line %d: missing new password\n" msgid "%s: line %d: missing new password\n"
msgstr "%s: Zeile %d: Neues Passwort fehlt\n" msgstr "%s: Zeile %d: Neues Passwort fehlt\n"
#, fuzzy, c-format
#| msgid "%s: Failed to write %s: %s\n"
msgid "%s: failed to crypt password with salt '%s': %s\n"
msgstr "%s: Schreiben von %s fehlgeschlagen: %s\n"
#, c-format #, c-format
msgid "%s: line %d: group '%s' does not exist\n" msgid "%s: line %d: group '%s' does not exist\n"
msgstr "%s: Zeile %d: Gruppe »%s« existiert nicht\n" msgstr "%s: Zeile %d: Gruppe »%s« existiert nicht\n"
@ -1109,6 +1119,16 @@ msgstr "%s: GID »%lu« existiert bereits.\n"
msgid "%s: Cannot setup cleanup service.\n" msgid "%s: Cannot setup cleanup service.\n"
msgstr "%s: Ihr Benutzername konnte nicht bestimmt werden.\n" msgstr "%s: Ihr Benutzername konnte nicht bestimmt werden.\n"
#, fuzzy
#| msgid ""
#| " -r, --reset reset the counters of login failures\n"
msgid ""
" -f, --force delete group even if it is the primary group "
"of a user\n"
msgstr ""
" -r, --reset Zähler fehlgeschlagener Anmeldungen\n"
" zurücksetzen\n"
#, c-format #, c-format
msgid "%s: cannot remove entry '%s' from %s\n" msgid "%s: cannot remove entry '%s' from %s\n"
msgstr "%s: Eintrag »%s« konnte nicht aus %s entfernt werden.\n" msgstr "%s: Eintrag »%s« konnte nicht aus %s entfernt werden.\n"
@ -1345,6 +1365,26 @@ msgstr ""
"älter\n" "älter\n"
" als TAGE sind\n" " als TAGE sind\n"
#, fuzzy
#| msgid ""
#| " -a, --all display faillog records for all users\n"
msgid ""
" -C, --clear clear lastlog record of an user (usable only "
"with -u)\n"
msgstr ""
" -a, --all Aufzeichnungen fehlgeschlagener Anmeldungen\n"
" für alle Benutzer anzeigen\n"
#, fuzzy
#| msgid ""
#| " -a, --all display faillog records for all users\n"
msgid ""
" -S, --set set lastlog record to current time (usable "
"only with -u)\n"
msgstr ""
" -a, --all Aufzeichnungen fehlgeschlagener Anmeldungen\n"
" für alle Benutzer anzeigen\n"
msgid "" msgid ""
" -t, --time DAYS print only lastlog records more recent than " " -t, --time DAYS print only lastlog records more recent than "
"DAYS\n" "DAYS\n"
@ -1367,6 +1407,24 @@ msgstr "Benutzername Port Letzter"
msgid "**Never logged in**" msgid "**Never logged in**"
msgstr "**Noch nie angemeldet**" msgstr "**Noch nie angemeldet**"
#, fuzzy, c-format
#| msgid "%s: Failed to get the entry for UID %lu\n"
msgid "%s: Failed to update the entry for UID %lu\n"
msgstr "%s: Auslesen des Eintrags für UID %lu fehlgeschlagen\n"
#, fuzzy, c-format
#| msgid "%s: failed to reset the lastlog entry of UID %lu: %s\n"
msgid "%s: Failed to update the lastlog file\n"
msgstr "%s: Zurücksetzen des lastlog-Eintrags für UID %lu fehlgeschlagen: %s\n"
#, c-format
msgid "%s: Option -C cannot be used together with option -S\n"
msgstr ""
#, c-format
msgid "%s: Options -C and -S require option -u to specify the user\n"
msgstr ""
#, c-format #, c-format
msgid "Usage: %s [-p] [name]\n" msgid "Usage: %s [-p] [name]\n"
msgstr "Aufruf: %s [-p] [Name]\n" msgstr "Aufruf: %s [-p] [Name]\n"
@ -1400,6 +1458,14 @@ msgstr ""
"\n" "\n"
"[Trennung abgebrochen -- root-Login erlaubt.]" "[Trennung abgebrochen -- root-Login erlaubt.]"
#, c-format
msgid "%s: Cannot possibly work without effective root\n"
msgstr "%s: Arbeit ohne effektive root-Rechte eventuell nicht möglich\n"
msgid "No utmp entry. You must exec \"login\" from the lowest level \"sh\""
msgstr ""
"Kein utmp-Eintrag. Sie müssen »login« vom niedrigsten »sh«-Level ausführen."
#, c-format #, c-format
msgid "" msgid ""
"\n" "\n"
@ -1409,14 +1475,6 @@ msgstr ""
"Login nach %u Sekunden wegen\n" "Login nach %u Sekunden wegen\n"
"Zeitüberschreitung abgebrochen.\n" "Zeitüberschreitung abgebrochen.\n"
#, c-format
msgid "%s: Cannot possibly work without effective root\n"
msgstr "%s: Arbeit ohne effektive root-Rechte eventuell nicht möglich\n"
msgid "No utmp entry. You must exec \"login\" from the lowest level \"sh\""
msgstr ""
"Kein utmp-Eintrag. Sie müssen »login« vom niedrigsten »sh«-Level ausführen."
#, c-format #, c-format
msgid "login: PAM Failure, aborting: %s\n" msgid "login: PAM Failure, aborting: %s\n"
msgstr "login: PAM-Fehler, Abbruch: %s\n" msgstr "login: PAM-Fehler, Abbruch: %s\n"
@ -1489,6 +1547,11 @@ msgstr "Aufruf: newgrp [-] [Gruppe]\n"
msgid "Usage: sg group [[-c] command]\n" msgid "Usage: sg group [[-c] command]\n"
msgstr "Aufruf: sg Gruppe [[-c] Befehl]\n" msgstr "Aufruf: sg Gruppe [[-c] Befehl]\n"
#, fuzzy, c-format
#| msgid "%s: Failed to write %s: %s\n"
msgid "%s: failed to crypt password with previous salt: %s\n"
msgstr "%s: Schreiben von %s fehlgeschlagen: %s\n"
msgid "Invalid password.\n" msgid "Invalid password.\n"
msgstr "Ungültiges Passwort.\n" msgstr "Ungültiges Passwort.\n"
@ -1557,6 +1620,21 @@ msgstr "%s: Zeile %d: chown %s (Eigentümer ändern) fehlgeschlagen: %s\n"
msgid "%s: line %d: can't update entry\n" msgid "%s: line %d: can't update entry\n"
msgstr "%s: Zeile %d: Eintrag kann nicht aktualisiert werden.\n" msgstr "%s: Zeile %d: Eintrag kann nicht aktualisiert werden.\n"
#, fuzzy, c-format
#| msgid "%s: failed to prepare the new %s entry '%s'\n"
msgid "%s: failed to prepare new %s entry\n"
msgstr "%s: Vorbereiten des neuen %s-Eintrags »%s« fehlgeschlagen.\n"
#, fuzzy, c-format
#| msgid "%s: can't create user\n"
msgid "%s: can't find subordinate user range\n"
msgstr "%s: Benutzer kann nicht erstellt werden\n"
#, fuzzy, c-format
#| msgid "%s: can't create group\n"
msgid "%s: can't find subordinate group range\n"
msgstr "%s: Gruppe kann nicht erzeugt werden\n"
msgid "" msgid ""
" -a, --all report password status on all accounts\n" " -a, --all report password status on all accounts\n"
msgstr "" msgstr ""
@ -1827,12 +1905,6 @@ msgstr "Passwort-Authentifizierung umgangen.\n"
msgid "Please enter your OWN password as authentication.\n" msgid "Please enter your OWN password as authentication.\n"
msgstr "Bitte geben Sie Ihr EIGENES Passwort als Authentifizierung ein.\n" msgstr "Bitte geben Sie Ihr EIGENES Passwort als Authentifizierung ein.\n"
msgid " ...killed.\n"
msgstr " ... abgeschossen.\n"
msgid " ...waiting for child to terminate.\n"
msgstr " ... Warten auf Beendigung des Kindprozesses.\n"
#, c-format #, c-format
msgid "%s: Cannot fork user shell\n" msgid "%s: Cannot fork user shell\n"
msgstr "%s: Prozessaufspaltung (fork) für Benutzer-Shell nicht möglich\n" msgstr "%s: Prozessaufspaltung (fork) für Benutzer-Shell nicht möglich\n"
@ -1848,13 +1920,19 @@ msgstr "%s: Signalmaskierungs-Fehlfunktion\n"
msgid "Session terminated, terminating shell..." msgid "Session terminated, terminating shell..."
msgstr "Sitzung abgebrochen, Shell wird beendet ..." msgstr "Sitzung abgebrochen, Shell wird beendet ..."
#, c-format msgid " ...killed.\n"
msgid "%s: %s\n" msgstr " ... abgeschossen.\n"
msgstr "%s: %s\n"
msgid " ...waiting for child to terminate.\n"
msgstr " ... Warten auf Beendigung des Kindprozesses.\n"
msgid " ...terminated.\n" msgid " ...terminated.\n"
msgstr " ... abgebrochen.\n" msgstr " ... abgebrochen.\n"
#, c-format
msgid "%s: %s\n"
msgstr "%s: %s\n"
msgid "" msgid ""
"Usage: su [options] [LOGIN]\n" "Usage: su [options] [LOGIN]\n"
"\n" "\n"
@ -2149,6 +2227,11 @@ msgstr "%s: Zurücksetzen des faillog-Eintrags für UID %lu fehlgeschlagen: %s\n
msgid "%s: failed to reset the lastlog entry of UID %lu: %s\n" msgid "%s: failed to reset the lastlog entry of UID %lu: %s\n"
msgstr "%s: Zurücksetzen des lastlog-Eintrags für UID %lu fehlgeschlagen: %s\n" msgstr "%s: Zurücksetzen des lastlog-Eintrags für UID %lu fehlgeschlagen: %s\n"
#, fuzzy, c-format
#| msgid "%s: failed to prepare the new %s entry '%s'\n"
msgid "%s: failed to prepare the new %s entry\n"
msgstr "%s: Vorbereiten des neuen %s-Eintrags »%s« fehlgeschlagen.\n"
#, c-format #, c-format
msgid "%s: cannot create directory %s\n" msgid "%s: cannot create directory %s\n"
msgstr "%s: Verzeichnis %s kann nicht erstellt werden.\n" msgstr "%s: Verzeichnis %s kann nicht erstellt werden.\n"
@ -2192,6 +2275,16 @@ msgstr "%s: Erstellen des tcb-Verzeichnisses für %s fehlgeschlagen\n"
msgid "%s: can't create group\n" msgid "%s: can't create group\n"
msgstr "%s: Gruppe kann nicht erzeugt werden\n" msgstr "%s: Gruppe kann nicht erzeugt werden\n"
#, fuzzy, c-format
#| msgid "%s: can't create user\n"
msgid "%s: can't create subordinate user IDs\n"
msgstr "%s: Benutzer kann nicht erstellt werden\n"
#, fuzzy, c-format
#| msgid "%s: can't create group\n"
msgid "%s: can't create subordinate group IDs\n"
msgstr "%s: Gruppe kann nicht erzeugt werden\n"
#, c-format #, c-format
msgid "" msgid ""
"%s: warning: the home directory already exists.\n" "%s: warning: the home directory already exists.\n"
@ -2243,6 +2336,11 @@ msgstr ""
"%s: Gruppe %s ist die primäre Gruppe eines anderen Benutzers und wird\n" "%s: Gruppe %s ist die primäre Gruppe eines anderen Benutzers und wird\n"
"nicht entfernt.\n" "nicht entfernt.\n"
#, fuzzy, c-format
#| msgid "%s: cannot remove entry '%s' from %s\n"
msgid "%s: cannot remove entry %lu from %s\n"
msgstr "%s: Eintrag »%s« konnte nicht aus %s entfernt werden.\n"
#, c-format #, c-format
msgid "%s: %s mail spool (%s) not found\n" msgid "%s: %s mail spool (%s) not found\n"
msgstr "%s: %s Mail-Warteschlange (%s) nicht gefunden\n" msgstr "%s: %s Mail-Warteschlange (%s) nicht gefunden\n"
@ -2368,6 +2466,18 @@ msgstr " -u, --uid UID Neue UID des Benutzerzugangs\n"
msgid " -U, --unlock unlock the user account\n" msgid " -U, --unlock unlock the user account\n"
msgstr " -U, --unlock Den Benutzerzugang entsperren\n" msgstr " -U, --unlock Den Benutzerzugang entsperren\n"
msgid " -v, --add-subuids FIRST-LAST add range of subordinate uids\n"
msgstr ""
msgid " -V, --del-subuids FIRST-LAST remove range of subordinate uids\n"
msgstr ""
msgid " -w, --add-subgids FIRST-LAST add range of subordinate gids\n"
msgstr ""
msgid " -W, --del-subgids FIRST-LAST remove range of subordinate gids\n"
msgstr ""
msgid "" msgid ""
" -Z, --selinux-user SEUSER new SELinux user mapping for the user " " -Z, --selinux-user SEUSER new SELinux user mapping for the user "
"account\n" "account\n"
@ -2389,6 +2499,16 @@ msgstr ""
msgid "%s: user '%s' already exists in %s\n" msgid "%s: user '%s' already exists in %s\n"
msgstr "%s: Benutzer »%s« existiert bereits in %s.\n" msgstr "%s: Benutzer »%s« existiert bereits in %s.\n"
#, fuzzy, c-format
#| msgid "%s: invalid date '%s'\n"
msgid "%s: invalid subordinate uid range '%s'\n"
msgstr "%s: Ungültiges Datum »%s«\n"
#, fuzzy, c-format
#| msgid "%s: invalid date '%s'\n"
msgid "%s: invalid subordinate gid range '%s'\n"
msgstr "%s: Ungültiges Datum »%s«\n"
#, c-format #, c-format
msgid "%s: no options\n" msgid "%s: no options\n"
msgstr "%s: keine Optionen\n" msgstr "%s: keine Optionen\n"
@ -2405,6 +2525,11 @@ msgstr "%s: shadow-Passwörter für -e und -f erforderlich\n"
msgid "%s: UID '%lu' already exists\n" msgid "%s: UID '%lu' already exists\n"
msgstr "%s: UID »%lu« existiert bereits\n" msgstr "%s: UID »%lu« existiert bereits\n"
#, fuzzy, c-format
#| msgid "%s: %s is not authorized to change the password of %s\n"
msgid "%s: %s does not exist, you cannot use the flags %s or %s\n"
msgstr "%s: %s ist nicht berechtigt, das Passwort von %s zu ändern.\n"
#, c-format #, c-format
msgid "%s: directory %s exists\n" msgid "%s: directory %s exists\n"
msgstr "%s: Verzeichnis %s existiert\n" msgstr "%s: Verzeichnis %s existiert\n"
@ -2452,6 +2577,26 @@ msgstr "Fehler beim Ändern des mailbox-Besitzers"
msgid "failed to rename mailbox" msgid "failed to rename mailbox"
msgstr "Fehler beim Umbenennen von mailbox" msgstr "Fehler beim Umbenennen von mailbox"
#, fuzzy, c-format
#| msgid "%s: failed to prepare the new %s entry '%s'\n"
msgid "%s: failed to remove uid range %lu-%lu from '%s'\n"
msgstr "%s: Vorbereiten des neuen %s-Eintrags »%s« fehlgeschlagen.\n"
#, fuzzy, c-format
#| msgid "%s: failed to prepare the new %s entry '%s'\n"
msgid "%s: failed to add uid range %lu-%lu from '%s'\n"
msgstr "%s: Vorbereiten des neuen %s-Eintrags »%s« fehlgeschlagen.\n"
#, fuzzy, c-format
#| msgid "%s: failed to prepare the new %s entry '%s'\n"
msgid "%s: failed to remove gid range %lu-%lu from '%s'\n"
msgstr "%s: Vorbereiten des neuen %s-Eintrags »%s« fehlgeschlagen.\n"
#, fuzzy, c-format
#| msgid "%s: failed to prepare the new %s entry '%s'\n"
msgid "%s: failed to add gid range %lu-%lu from '%s'\n"
msgstr "%s: Vorbereiten des neuen %s-Eintrags »%s« fehlgeschlagen.\n"
#, c-format #, c-format
msgid "" msgid ""
"You have modified %s.\n" "You have modified %s.\n"
@ -2506,6 +2651,20 @@ msgstr "Datei konnte nicht gesperrt werden"
msgid "Couldn't make backup" msgid "Couldn't make backup"
msgstr "Sicherung konnte nicht erstellt werden" msgstr "Sicherung konnte nicht erstellt werden"
#, fuzzy, c-format
#| msgid "%s: PAM: %s\n"
msgid "%s: %s: %s\n"
msgstr "%s: PAM: %s\n"
#, fuzzy, c-format
#| msgid "%s: nscd exited with status %d\n"
msgid "%s: %s returned with status %d\n"
msgstr "%s: nscd wurde mit Status %d beendet\n"
#, c-format
msgid "%s: %s killed by signal %d\n"
msgstr ""
msgid "failed to open scratch file" msgid "failed to open scratch file"
msgstr "Öffnen der scratch-Datei fehlgeschlagen" msgstr "Öffnen der scratch-Datei fehlgeschlagen"
@ -2530,4 +2689,3 @@ msgstr ""
#, c-format #, c-format
msgid "%s: failed to find tcb directory for %s\n" msgid "%s: failed to find tcb directory for %s\n"
msgstr "%s: tcb-Verzeichnis für %s konnte nicht gefunden werden\n" msgstr "%s: tcb-Verzeichnis für %s konnte nicht gefunden werden\n"

21335
po/fr.po

File diff suppressed because it is too large Load Diff

View File

@ -785,7 +785,6 @@ msgid "%s: line %d: missing new password\n"
msgstr "%s: жол %d: жаңа пароль жоқ\n" msgstr "%s: жол %d: жаңа пароль жоқ\n"
#, c-format #, c-format
#| msgid "%s: Failed to write %s: %s\n"
msgid "%s: failed to crypt password with salt '%s': %s\n" msgid "%s: failed to crypt password with salt '%s': %s\n"
msgstr "%s: парольді '%s' тұзымен шифрлеу сәтсіз аяқталды: %s\n" msgstr "%s: парольді '%s' тұзымен шифрлеу сәтсіз аяқталды: %s\n"
@ -1095,8 +1094,6 @@ msgstr "%s: GID '%lu' бар болып тұр\n"
msgid "%s: Cannot setup cleanup service.\n" msgid "%s: Cannot setup cleanup service.\n"
msgstr "%s: Тазарту қызметін орнату мүмкін емес.\n" msgstr "%s: Тазарту қызметін орнату мүмкін емес.\n"
#| msgid ""
#| " -r, --reset reset the counters of login failures\n"
msgid "" msgid ""
" -f, --force delete group even if it is the primary group " " -f, --force delete group even if it is the primary group "
"of a user\n" "of a user\n"
@ -1330,8 +1327,6 @@ msgstr ""
" -b, --before КҮН мерзімі КҮНнен үлкен ғана lastlog жазбаларын " " -b, --before КҮН мерзімі КҮНнен үлкен ғана lastlog жазбаларын "
"көрсету\n" "көрсету\n"
#| msgid ""
#| " -a, --all display faillog records for all users\n"
msgid "" msgid ""
" -C, --clear clear lastlog record of an user (usable only " " -C, --clear clear lastlog record of an user (usable only "
"with -u)\n" "with -u)\n"
@ -1339,8 +1334,6 @@ msgstr ""
" -C, --clear пайдаланушының lastlog жазбасын тазарту (тек " " -C, --clear пайдаланушының lastlog жазбасын тазарту (тек "
"-u опциясымен бірге пайдаланылады)\n" "-u опциясымен бірге пайдаланылады)\n"
#| msgid ""
#| " -a, --all display faillog records for all users\n"
msgid "" msgid ""
" -S, --set set lastlog record to current time (usable " " -S, --set set lastlog record to current time (usable "
"only with -u)\n" "only with -u)\n"
@ -1511,7 +1504,6 @@ msgid "Usage: sg group [[-c] command]\n"
msgstr "Қолданылуы: sg топ [[-c] командасы]\n" msgstr "Қолданылуы: sg топ [[-c] командасы]\n"
#, c-format #, c-format
#| msgid "%s: Failed to write %s: %s\n"
msgid "%s: failed to crypt password with previous salt: %s\n" msgid "%s: failed to crypt password with previous salt: %s\n"
msgstr "%s: парольді алдыңғы тұзбен шифрлеу сәтсіз аяқталды: %s\n" msgstr "%s: парольді алдыңғы тұзбен шифрлеу сәтсіз аяқталды: %s\n"
@ -1587,7 +1579,6 @@ msgid "%s: failed to prepare new %s entry\n"
msgstr "%s: жаңа %s жазбасын дайындау сәтсіз аяқталды\n" msgstr "%s: жаңа %s жазбасын дайындау сәтсіз аяқталды\n"
#, c-format #, c-format
#| msgid "%s: can't create user\n"
msgid "%s: can't find subordinate user range\n" msgid "%s: can't find subordinate user range\n"
msgstr "%s: бағынышты пайдаланушы ауқымын табу мүмкін емес\n" msgstr "%s: бағынышты пайдаланушы ауқымын табу мүмкін емес\n"
@ -2006,7 +1997,6 @@ msgid "%s: line too long in %s: %s..."
msgstr "%s: %s ішіндегі жол тым ұзын: %s..." msgstr "%s: %s ішіндегі жол тым ұзын: %s..."
#, c-format #, c-format
#| msgid "%s: Cannot create symbolic link %s: %s\n"
msgid "%s: Cannot create backup file (%s): %s\n" msgid "%s: Cannot create backup file (%s): %s\n"
msgstr "%s: Қор көшірме файлын жасау мүмкін емес (%s): %s\n" msgstr "%s: Қор көшірме файлын жасау мүмкін емес (%s): %s\n"
@ -2218,7 +2208,6 @@ msgid "%s: can't create group\n"
msgstr "%s: топты құру мүмкін емес\n" msgstr "%s: топты құру мүмкін емес\n"
#, c-format #, c-format
#| msgid "%s: can't create user\n"
msgid "%s: can't create subordinate user IDs\n" msgid "%s: can't create subordinate user IDs\n"
msgstr "%s: бағынышты пайдаланушы ID-ын жасау мүмкін емес\n" msgstr "%s: бағынышты пайдаланушы ID-ын жасау мүмкін емес\n"
@ -2430,7 +2419,6 @@ msgid "%s: user '%s' already exists in %s\n"
msgstr "%s: '%s' пайдаланушысы %s ішінде бар болып тұр\n" msgstr "%s: '%s' пайдаланушысы %s ішінде бар болып тұр\n"
#, c-format #, c-format
#| msgid "%s: invalid date '%s'\n"
msgid "%s: invalid subordinate uid range '%s'\n" msgid "%s: invalid subordinate uid range '%s'\n"
msgstr "%s: жарамсыз бағынышты uid ауқымы '%s'\n" msgstr "%s: жарамсыз бағынышты uid ауқымы '%s'\n"
@ -2455,7 +2443,6 @@ msgid "%s: UID '%lu' already exists\n"
msgstr "%s: '%lu' UID-і бар болып тұр\n" msgstr "%s: '%lu' UID-і бар болып тұр\n"
#, c-format #, c-format
#| msgid "%s: %s is not authorized to change the password of %s\n"
msgid "%s: %s does not exist, you cannot use the flags %s or %s\n" msgid "%s: %s does not exist, you cannot use the flags %s or %s\n"
msgstr "%s: %s жоқ болып тұр, %s немесе %s жалаушаларын қолдануға болмайды\n" msgstr "%s: %s жоқ болып тұр, %s немесе %s жалаушаларын қолдануға болмайды\n"
@ -2504,7 +2491,6 @@ msgid "failed to rename mailbox"
msgstr "mailbox атын ауыстыру қатемен аяқталды" msgstr "mailbox атын ауыстыру қатемен аяқталды"
#, c-format #, c-format
#| msgid "%s: failed to prepare the new %s entry '%s'\n"
msgid "%s: failed to remove uid range %lu-%lu from '%s'\n" msgid "%s: failed to remove uid range %lu-%lu from '%s'\n"
msgstr "%s: %lu-%lu uid-тар ауқымын '%s' ішінен өшіру сәтсіз аяқталды\n" msgstr "%s: %lu-%lu uid-тар ауқымын '%s' ішінен өшіру сәтсіз аяқталды\n"
@ -2574,7 +2560,6 @@ msgid "Couldn't make backup"
msgstr "Қор көшірмені жасау мүмкін емес" msgstr "Қор көшірмені жасау мүмкін емес"
#, c-format #, c-format
#| msgid "%s: PAM: %s\n"
msgid "%s: %s: %s\n" msgid "%s: %s: %s\n"
msgstr "%s: %s: %s\n" msgstr "%s: %s: %s\n"

View File

@ -2636,7 +2636,9 @@ msgstr "%s: %s sloot af met status %d\n"
msgid "%s: %s killed by signal %d\n" msgid "%s: %s killed by signal %d\n"
msgstr "%s: %s werd vernietigd door signaal %d\n" msgstr "%s: %s werd vernietigd door signaal %d\n"
msgid "failed to open scratch file\n" #, fuzzy
#| msgid "failed to open scratch file\n"
msgid "failed to open scratch file"
msgstr "initieel bestand openen is mislukt\n" msgstr "initieel bestand openen is mislukt\n"
msgid "failed to unlink scratch file" msgid "failed to unlink scratch file"

View File

@ -77,6 +77,8 @@ static gid_t group_id;
static /*@null@*/char *group_passwd; static /*@null@*/char *group_passwd;
static /*@null@*/char *empty_list = NULL; static /*@null@*/char *empty_list = NULL;
static const char *prefix = "";
static bool oflg = false; /* permit non-unique group ID to be specified with -g */ static bool oflg = false; /* permit non-unique group ID to be specified with -g */
static bool gflg = false; /* ID value for the new group */ static bool gflg = false; /* ID value for the new group */
static bool fflg = false; /* if group already exists, do nothing and exit(0) */ static bool fflg = false; /* if group already exists, do nothing and exit(0) */
@ -123,6 +125,7 @@ static /*@noreturn@*/void usage (int status)
(void) fputs (_(" -p, --password PASSWORD use this encrypted password for the new group\n"), usageout); (void) fputs (_(" -p, --password PASSWORD use this encrypted password for the new group\n"), usageout);
(void) fputs (_(" -r, --system create a system account\n"), usageout); (void) fputs (_(" -r, --system create a system account\n"), usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
(void) fputs (_(" -P, --prefix PREFIX_DIR directory prefix\n"), usageout);
(void) fputs ("\n", usageout); (void) fputs ("\n", usageout);
exit (status); exit (status);
} }
@ -386,10 +389,11 @@ static void process_flags (int argc, char **argv)
{"password", required_argument, NULL, 'p'}, {"password", required_argument, NULL, 'p'},
{"system", no_argument, NULL, 'r'}, {"system", no_argument, NULL, 'r'},
{"root", required_argument, NULL, 'R'}, {"root", required_argument, NULL, 'R'},
{"prefix", required_argument, NULL, 'P'},
{NULL, 0, NULL, '\0'} {NULL, 0, NULL, '\0'}
}; };
while ((c = getopt_long (argc, argv, "fg:hK:op:rR:", while ((c = getopt_long (argc, argv, "fg:hK:op:rR:P:",
long_options, NULL)) != -1) { long_options, NULL)) != -1) {
switch (c) { switch (c) {
case 'f': case 'f':
@ -446,6 +450,8 @@ static void process_flags (int argc, char **argv)
break; break;
case 'R': /* no-op, handled in process_root_flag () */ case 'R': /* no-op, handled in process_root_flag () */
break; break;
case 'P': /* no-op, handled in process_prefix_flag () */
break;
default: default:
usage (E_USAGE); usage (E_USAGE);
} }
@ -480,7 +486,7 @@ static void check_flags (void)
* Check if the group already exist. * Check if the group already exist.
*/ */
/* local, no need for xgetgrnam */ /* local, no need for xgetgrnam */
if (getgrnam (group_name) != NULL) { if (prefix_getgrnam (group_name) != NULL) {
/* The group already exist */ /* The group already exist */
if (fflg) { if (fflg) {
/* OK, no need to do anything */ /* OK, no need to do anything */
@ -492,7 +498,7 @@ static void check_flags (void)
exit (E_NAME_IN_USE); exit (E_NAME_IN_USE);
} }
if (gflg && (getgrgid (group_id) != NULL)) { if (gflg && (prefix_getgrgid (group_id) != NULL)) {
/* A GID was specified, and a group already exist with that GID /* A GID was specified, and a group already exist with that GID
* - either we will use this GID anyway (-o) * - either we will use this GID anyway (-o)
* - either we ignore the specified GID and * - either we ignore the specified GID and
@ -578,6 +584,7 @@ int main (int argc, char **argv)
(void) textdomain (PACKAGE); (void) textdomain (PACKAGE);
process_root_flag ("-R", argc, argv); process_root_flag ("-R", argc, argv);
prefix = process_prefix_flag ("-P", argc, argv);
OPENLOG ("groupadd"); OPENLOG ("groupadd");
#ifdef WITH_AUDIT #ifdef WITH_AUDIT

View File

@ -62,6 +62,8 @@ static char *group_name;
static gid_t group_id = -1; static gid_t group_id = -1;
static bool check_group_busy = true; static bool check_group_busy = true;
static const char* prefix = "";
#ifdef SHADOWGRP #ifdef SHADOWGRP
static bool is_shadow_grp; static bool is_shadow_grp;
#endif #endif
@ -97,6 +99,7 @@ static /*@noreturn@*/void usage (int status)
Prog); Prog);
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout); (void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
(void) fputs (_(" -P, --prefix PREFIX_DIR prefix directory where are located the /etc/* files\n"), usageout);
(void) fputs (_(" -f, --force delete group even if it is the primary group of a user\n"), usageout); (void) fputs (_(" -f, --force delete group even if it is the primary group of a user\n"), usageout);
(void) fputs ("\n", usageout); (void) fputs ("\n", usageout);
exit (status); exit (status);
@ -283,11 +286,11 @@ static void group_busy (gid_t gid)
* Nice slow linear search. * Nice slow linear search.
*/ */
setpwent (); prefix_setpwent ();
while ( ((pwd = getpwent ()) != NULL) && (pwd->pw_gid != gid) ); while ( ((pwd = prefix_getpwent ()) != NULL) && (pwd->pw_gid != gid) );
endpwent (); prefix_endpwent ();
/* /*
* If pwd isn't NULL, it stopped because the gid's matched. * If pwd isn't NULL, it stopped because the gid's matched.
@ -320,10 +323,11 @@ static void process_flags (int argc, char **argv)
static struct option long_options[] = { static struct option long_options[] = {
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{"root", required_argument, NULL, 'R'}, {"root", required_argument, NULL, 'R'},
{"prefix", required_argument, NULL, 'P'},
{NULL, 0, NULL, '\0'} {NULL, 0, NULL, '\0'}
}; };
while ((c = getopt_long (argc, argv, "hfR:", while ((c = getopt_long (argc, argv, "hfR:P:",
long_options, NULL)) != -1) { long_options, NULL)) != -1) {
switch (c) { switch (c) {
case 'h': case 'h':
@ -331,6 +335,8 @@ static void process_flags (int argc, char **argv)
/*@notreached@*/break; /*@notreached@*/break;
case 'R': /* no-op, handled in process_root_flag () */ case 'R': /* no-op, handled in process_root_flag () */
break; break;
case 'P': /* no-op, handled in process_prefix_flag () */
break;
case 'f': case 'f':
check_group_busy = false; check_group_busy = false;
break; break;
@ -374,6 +380,7 @@ int main (int argc, char **argv)
(void) textdomain (PACKAGE); (void) textdomain (PACKAGE);
process_root_flag ("-R", argc, argv); process_root_flag ("-R", argc, argv);
prefix = process_prefix_flag ("-P", argc, argv);
OPENLOG ("groupdel"); OPENLOG ("groupdel");
#ifdef WITH_AUDIT #ifdef WITH_AUDIT
@ -434,7 +441,7 @@ int main (int argc, char **argv)
/* /*
* Start with a quick check to see if the group exists. * Start with a quick check to see if the group exists.
*/ */
grp = getgrnam (group_name); /* local, no need for xgetgrnam */ grp = prefix_getgrnam (group_name); /* local, no need for xgetgrnam */
if (NULL == grp) { if (NULL == grp) {
fprintf (stderr, fprintf (stderr,
_("%s: group '%s' does not exist\n"), _("%s: group '%s' does not exist\n"),

View File

@ -85,6 +85,8 @@ static char *group_passwd;
static gid_t group_id; static gid_t group_id;
static gid_t group_newid; static gid_t group_newid;
static const char* prefix = "";
static struct cleanup_info_mod info_passwd; static struct cleanup_info_mod info_passwd;
static struct cleanup_info_mod info_group; static struct cleanup_info_mod info_group;
#ifdef SHADOWGRP #ifdef SHADOWGRP
@ -133,6 +135,7 @@ static void usage (int status)
(void) fputs (_(" -p, --password PASSWORD change the password to this (encrypted)\n" (void) fputs (_(" -p, --password PASSWORD change the password to this (encrypted)\n"
" PASSWORD\n"), usageout); " PASSWORD\n"), usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
(void) fputs (_(" -P, --prefix PREFIX_DIR prefix directory where are located the /etc/* files\n"), usageout);
(void) fputs ("\n", usageout); (void) fputs ("\n", usageout);
exit (status); exit (status);
} }
@ -345,7 +348,7 @@ static void check_new_name (void)
* If the entry is found, too bad. * If the entry is found, too bad.
*/ */
/* local, no need for xgetgrnam */ /* local, no need for xgetgrnam */
if (getgrnam (group_newname) != NULL) { if (prefix_getgrnam (group_newname) != NULL) {
fprintf (stderr, fprintf (stderr,
_("%s: group '%s' already exists\n"), _("%s: group '%s' already exists\n"),
Prog, group_newname); Prog, group_newname);
@ -381,9 +384,10 @@ static void process_flags (int argc, char **argv)
{"non-unique", no_argument, NULL, 'o'}, {"non-unique", no_argument, NULL, 'o'},
{"password", required_argument, NULL, 'p'}, {"password", required_argument, NULL, 'p'},
{"root", required_argument, NULL, 'R'}, {"root", required_argument, NULL, 'R'},
{"prefix", required_argument, NULL, 'P'},
{NULL, 0, NULL, '\0'} {NULL, 0, NULL, '\0'}
}; };
while ((c = getopt_long (argc, argv, "g:hn:op:R:", while ((c = getopt_long (argc, argv, "g:hn:op:R:P:",
long_options, NULL)) != -1) { long_options, NULL)) != -1) {
switch (c) { switch (c) {
case 'g': case 'g':
@ -412,6 +416,8 @@ static void process_flags (int argc, char **argv)
break; break;
case 'R': /* no-op, handled in process_root_flag () */ case 'R': /* no-op, handled in process_root_flag () */
break; break;
case 'P': /* no-op, handled in process_prefix_flag () */
break;
default: default:
usage (E_USAGE); usage (E_USAGE);
} }
@ -702,8 +708,8 @@ void update_primary_groups (gid_t ogid, gid_t ngid)
{ {
struct passwd *pwd; struct passwd *pwd;
setpwent (); prefix_setpwent ();
while ((pwd = getpwent ()) != NULL) { while ((pwd = prefix_getpwent ()) != NULL) {
if (pwd->pw_gid == ogid) { if (pwd->pw_gid == ogid) {
const struct passwd *lpwd; const struct passwd *lpwd;
struct passwd npwd; struct passwd npwd;
@ -725,7 +731,7 @@ void update_primary_groups (gid_t ogid, gid_t ngid)
} }
} }
} }
endpwent (); prefix_endpwent ();
} }
/* /*
@ -751,6 +757,7 @@ int main (int argc, char **argv)
(void) textdomain (PACKAGE); (void) textdomain (PACKAGE);
process_root_flag ("-R", argc, argv); process_root_flag ("-R", argc, argv);
prefix = process_prefix_flag ("-P", argc, argv);
OPENLOG ("groupmod"); OPENLOG ("groupmod");
#ifdef WITH_AUDIT #ifdef WITH_AUDIT
@ -810,7 +817,7 @@ int main (int argc, char **argv)
/* /*
* Start with a quick check to see if the group exists. * Start with a quick check to see if the group exists.
*/ */
grp = getgrnam (group_name); /* local, no need for xgetgrnam */ grp = prefix_getgrnam (group_name); /* local, no need for xgetgrnam */
if (NULL == grp) { if (NULL == grp) {
fprintf (stderr, fprintf (stderr,
_("%s: group '%s' does not exist\n"), _("%s: group '%s' does not exist\n"),

View File

@ -115,6 +115,10 @@ static const char *user_comment = "";
static const char *user_home = ""; static const char *user_home = "";
static const char *user_shell = ""; static const char *user_shell = "";
static const char *create_mail_spool = ""; static const char *create_mail_spool = "";
static const char *prefix = "";
static const char *prefix_user_home = NULL;
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
static /*@notnull@*/const char *user_selinux = ""; static /*@notnull@*/const char *user_selinux = "";
#endif /* WITH_SELINUX */ #endif /* WITH_SELINUX */
@ -226,11 +230,11 @@ static void create_mail (void);
static void fail_exit (int code) static void fail_exit (int code)
{ {
if (home_added) { if (home_added) {
if (rmdir (user_home) != 0) { if (rmdir (prefix_user_home) != 0) {
fprintf (stderr, fprintf (stderr,
_("%s: %s was created, but could not be removed\n"), _("%s: %s was created, but could not be removed\n"),
Prog, user_home); Prog, prefix_user_home);
SYSLOG ((LOG_ERR, "failed to remove %s", user_home)); SYSLOG ((LOG_ERR, "failed to remove %s", prefix_user_home));
} }
} }
@ -339,14 +343,25 @@ static void fail_exit (int code)
static void get_defaults (void) static void get_defaults (void)
{ {
FILE *fp; FILE *fp;
char* default_file = USER_DEFAULTS_FILE;
char buf[1024]; char buf[1024];
char *cp; char *cp;
if(prefix[0]) {
size_t len;
int wlen;
len = strlen(prefix) + strlen(USER_DEFAULTS_FILE) + 2;
default_file = malloc(len);
wlen = snprintf(default_file, len, "%s/%s", prefix, USER_DEFAULTS_FILE);
assert (wlen == (int) len -1);
}
/* /*
* Open the defaults file for reading. * Open the defaults file for reading.
*/ */
fp = fopen (USER_DEFAULTS_FILE, "r"); fp = fopen (default_file, "r");
if (NULL == fp) { if (NULL == fp) {
return; return;
} }
@ -372,14 +387,14 @@ static void get_defaults (void)
* Primary GROUP identifier * Primary GROUP identifier
*/ */
if (MATCH (buf, DGROUP)) { if (MATCH (buf, DGROUP)) {
const struct group *grp = getgr_nam_gid (cp); const struct group *grp = prefix_getgr_nam_gid (cp);
if (NULL == grp) { if (NULL == grp) {
fprintf (stderr, fprintf (stderr,
_("%s: group '%s' does not exist\n"), _("%s: group '%s' does not exist\n"),
Prog, cp); Prog, cp);
fprintf (stderr, fprintf (stderr,
_("%s: the %s configuration in %s will be ignored\n"), _("%s: the %s configuration in %s will be ignored\n"),
Prog, DGROUP, USER_DEFAULTS_FILE); Prog, DGROUP, default_file);
} else { } else {
def_group = grp->gr_gid; def_group = grp->gr_gid;
def_gname = xstrdup (grp->gr_name); def_gname = xstrdup (grp->gr_name);
@ -411,7 +426,7 @@ static void get_defaults (void)
Prog, cp); Prog, cp);
fprintf (stderr, fprintf (stderr,
_("%s: the %s configuration in %s will be ignored\n"), _("%s: the %s configuration in %s will be ignored\n"),
Prog, DINACT, USER_DEFAULTS_FILE); Prog, DINACT, default_file);
def_inactive = -1; def_inactive = -1;
} }
} }
@ -431,8 +446,21 @@ static void get_defaults (void)
cp = SKEL_DIR; /* XXX warning: const */ cp = SKEL_DIR; /* XXX warning: const */
} }
if(prefix[0]) {
size_t len;
int wlen;
char* _def_template; /* avoid const warning */
len = strlen(prefix) + strlen(cp) + 2;
_def_template = xmalloc(len);
wlen = snprintf(_def_template, len, "%s/%s", prefix, cp);
assert (wlen == (int) len -1);
def_template = _def_template;
}
else {
def_template = xstrdup (cp); def_template = xstrdup (cp);
} }
}
/* /*
* Create by default user mail spool or not ? * Create by default user mail spool or not ?
@ -446,6 +474,10 @@ static void get_defaults (void)
} }
} }
(void) fclose (fp); (void) fclose (fp);
if(prefix[0]) {
free(default_file);
}
} }
/* /*
@ -477,7 +509,8 @@ static int set_defaults (void)
FILE *ifp; FILE *ifp;
FILE *ofp; FILE *ofp;
char buf[1024]; char buf[1024];
static char new_file[] = NEW_USER_FILE; char* new_file = NEW_USER_FILE;
char* default_file = USER_DEFAULTS_FILE;
char *cp; char *cp;
int ofd; int ofd;
int wlen; int wlen;
@ -489,6 +522,20 @@ static int set_defaults (void)
bool out_skel = false; bool out_skel = false;
bool out_create_mail_spool = false; bool out_create_mail_spool = false;
if(prefix[0]) {
size_t len;
len = strlen(prefix) + strlen(NEW_USER_FILE) + 2;
new_file = malloc(len);
wlen = snprintf(new_file, len, "%s/%s", prefix, NEW_USER_FILE);
assert (wlen == (int) len -1);
len = strlen(prefix) + strlen(USER_DEFAULTS_FILE) + 2;
default_file = malloc(len);
wlen = snprintf(default_file, len, "%s/%s", prefix, USER_DEFAULTS_FILE);
assert (wlen == (int) len -1);
}
/* /*
* Create a temporary file to copy the new output to. * Create a temporary file to copy the new output to.
*/ */
@ -513,7 +560,7 @@ static int set_defaults (void)
* temporary file, using any new values. Each line is checked * temporary file, using any new values. Each line is checked
* to insure that it is not output more than once. * to insure that it is not output more than once.
*/ */
ifp = fopen (USER_DEFAULTS_FILE, "r"); ifp = fopen (default_file, "r");
if (NULL == ifp) { if (NULL == ifp) {
fprintf (ofp, "# useradd defaults file\n"); fprintf (ofp, "# useradd defaults file\n");
goto skip; goto skip;
@ -530,7 +577,7 @@ static int set_defaults (void)
if (feof (ifp) == 0) { if (feof (ifp) == 0) {
fprintf (stderr, fprintf (stderr,
_("%s: line too long in %s: %s..."), _("%s: line too long in %s: %s..."),
Prog, USER_DEFAULTS_FILE, buf); Prog, default_file, buf);
(void) fclose (ifp); (void) fclose (ifp);
return -1; return -1;
} }
@ -602,10 +649,10 @@ static int set_defaults (void)
/* /*
* Rename the current default file to its backup name. * Rename the current default file to its backup name.
*/ */
wlen = snprintf (buf, sizeof buf, "%s-", USER_DEFAULTS_FILE); wlen = snprintf (buf, sizeof buf, "%s-", default_file);
assert (wlen < (int) sizeof buf); assert (wlen < (int) sizeof buf);
unlink (buf); unlink (buf);
if ((link (USER_DEFAULTS_FILE, buf) != 0) && (ENOENT != errno)) { if ((link (default_file, buf) != 0) && (ENOENT != errno)) {
int err = errno; int err = errno;
fprintf (stderr, fprintf (stderr,
_("%s: Cannot create backup file (%s): %s\n"), _("%s: Cannot create backup file (%s): %s\n"),
@ -617,7 +664,7 @@ static int set_defaults (void)
/* /*
* Rename the new default file to its correct name. * Rename the new default file to its correct name.
*/ */
if (rename (new_file, USER_DEFAULTS_FILE) != 0) { if (rename (new_file, default_file) != 0) {
int err = errno; int err = errno;
fprintf (stderr, fprintf (stderr,
_("%s: rename: %s: %s\n"), _("%s: rename: %s: %s\n"),
@ -636,6 +683,12 @@ static int set_defaults (void)
(unsigned int) def_group, def_home, def_shell, (unsigned int) def_group, def_home, def_shell,
def_inactive, def_expire, def_template, def_inactive, def_expire, def_template,
def_create_mail_spool)); def_create_mail_spool));
if(prefix[0]) {
free(new_file);
free(default_file);
}
return 0; return 0;
} }
@ -675,7 +728,7 @@ static int get_groups (char *list)
* Names starting with digits are treated as numerical * Names starting with digits are treated as numerical
* GID values, otherwise the string is looked up as is. * GID values, otherwise the string is looked up as is.
*/ */
grp = getgr_nam_gid (list); grp = prefix_getgr_nam_gid (list);
/* /*
* There must be a match, either by GID value or by * There must be a match, either by GID value or by
@ -775,6 +828,7 @@ static void usage (int status)
(void) fputs (_(" -p, --password PASSWORD encrypted password of the new account\n"), usageout); (void) fputs (_(" -p, --password PASSWORD encrypted password of the new account\n"), usageout);
(void) fputs (_(" -r, --system create a system account\n"), usageout); (void) fputs (_(" -r, --system create a system account\n"), usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
(void) fputs (_(" -P, --prefix PREFIX_DIR prefix directory where are located the /etc/* files\n"), usageout);
(void) fputs (_(" -s, --shell SHELL login shell of the new account\n"), usageout); (void) fputs (_(" -s, --shell SHELL login shell of the new account\n"), usageout);
(void) fputs (_(" -u, --uid UID user ID of the new account\n"), usageout); (void) fputs (_(" -u, --uid UID user ID of the new account\n"), usageout);
(void) fputs (_(" -U, --user-group create a group with the same name as the user\n"), usageout); (void) fputs (_(" -U, --user-group create a group with the same name as the user\n"), usageout);
@ -1049,6 +1103,7 @@ static void process_flags (int argc, char **argv)
{"password", required_argument, NULL, 'p'}, {"password", required_argument, NULL, 'p'},
{"system", no_argument, NULL, 'r'}, {"system", no_argument, NULL, 'r'},
{"root", required_argument, NULL, 'R'}, {"root", required_argument, NULL, 'R'},
{"prefix", required_argument, NULL, 'P'},
{"shell", required_argument, NULL, 's'}, {"shell", required_argument, NULL, 's'},
{"uid", required_argument, NULL, 'u'}, {"uid", required_argument, NULL, 'u'},
{"user-group", no_argument, NULL, 'U'}, {"user-group", no_argument, NULL, 'U'},
@ -1059,9 +1114,9 @@ static void process_flags (int argc, char **argv)
}; };
while ((c = getopt_long (argc, argv, while ((c = getopt_long (argc, argv,
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
"b:c:d:De:f:g:G:hk:K:lmMNop:rR:s:u:UZ:", "b:c:d:De:f:g:G:hk:K:lmMNop:rR:P:s:u:UZ:",
#else /* !WITH_SELINUX */ #else /* !WITH_SELINUX */
"b:c:d:De:f:g:G:hk:K:lmMNop:rR:s:u:U", "b:c:d:De:f:g:G:hk:K:lmMNop:rR:P:s:u:U",
#endif /* !WITH_SELINUX */ #endif /* !WITH_SELINUX */
long_options, NULL)) != -1) { long_options, NULL)) != -1) {
switch (c) { switch (c) {
@ -1152,7 +1207,7 @@ static void process_flags (int argc, char **argv)
fflg = true; fflg = true;
break; break;
case 'g': case 'g':
grp = getgr_nam_gid (optarg); grp = prefix_getgr_nam_gid (optarg);
if (NULL == grp) { if (NULL == grp) {
fprintf (stderr, fprintf (stderr,
_("%s: group '%s' does not exist\n"), _("%s: group '%s' does not exist\n"),
@ -1232,6 +1287,8 @@ static void process_flags (int argc, char **argv)
break; break;
case 'R': /* no-op, handled in process_root_flag () */ case 'R': /* no-op, handled in process_root_flag () */
break; break;
case 'P': /* no-op, handled in process_prefix_flag () */
break;
case 's': case 's':
if ( ( !VALID (optarg) ) if ( ( !VALID (optarg) )
|| ( ('\0' != optarg[0]) || ( ('\0' != optarg[0])
@ -1261,6 +1318,12 @@ static void process_flags (int argc, char **argv)
break; break;
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
case 'Z': case 'Z':
if (prefix[0]) {
fprintf (stderr,
_("%s: -Z cannot be used with --prefix\n"),
Prog);
exit (E_BAD_ARG);
}
if (is_selinux_enabled () > 0) { if (is_selinux_enabled () > 0) {
user_selinux = optarg; user_selinux = optarg;
} else { } else {
@ -1360,6 +1423,18 @@ static void process_flags (int argc, char **argv)
user_home = uh; user_home = uh;
} }
if(prefix[0]) {
size_t len = strlen(prefix) + strlen(user_home) + 2;
int wlen;
char* _prefix_user_home; /* to avoid const warning */
_prefix_user_home = xmalloc(len);
wlen = snprintf(_prefix_user_home, len, "%s/%s", prefix, user_home);
assert (wlen == (int) len -1);
prefix_user_home = _prefix_user_home;
}
else {
prefix_user_home = user_home;
}
} }
if (!eflg) { if (!eflg) {
@ -1872,7 +1947,7 @@ static void usr_update (void)
* are left unchanged). --marekm * are left unchanged). --marekm
*/ */
/* local, no need for xgetpwuid */ /* local, no need for xgetpwuid */
if ((!lflg) && (getpwuid (user_id) == NULL)) { if ((!lflg) && (prefix_getpwuid (user_id) == NULL)) {
faillog_reset (user_id); faillog_reset (user_id);
lastlog_reset (user_id); lastlog_reset (user_id);
} }
@ -1942,9 +2017,9 @@ static void usr_update (void)
*/ */
static void create_home (void) static void create_home (void)
{ {
if (access (user_home, F_OK) != 0) { if (access (prefix_user_home, F_OK) != 0) {
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
if (set_selinux_file_context (user_home) != 0) { if (set_selinux_file_context (prefix_user_home) != 0) {
fprintf (stderr, fprintf (stderr,
_("%s: cannot set SELinux context for home directory %s\n"), _("%s: cannot set SELinux context for home directory %s\n"),
Prog, user_home); Prog, user_home);
@ -1952,10 +2027,10 @@ static void create_home (void)
} }
#endif #endif
/* XXX - create missing parent directories. --marekm */ /* XXX - create missing parent directories. --marekm */
if (mkdir (user_home, 0) != 0) { if (mkdir (prefix_user_home, 0) != 0) {
fprintf (stderr, fprintf (stderr,
_("%s: cannot create directory %s\n"), _("%s: cannot create directory %s\n"),
Prog, user_home); Prog, prefix_user_home);
#ifdef WITH_AUDIT #ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_USER, Prog, audit_logger (AUDIT_ADD_USER, Prog,
"adding home directory", "adding home directory",
@ -1964,8 +2039,8 @@ static void create_home (void)
#endif #endif
fail_exit (E_HOMEDIR); fail_exit (E_HOMEDIR);
} }
chown (user_home, user_id, user_gid); (void) chown (prefix_user_home, user_id, user_gid);
chmod (user_home, chmod (prefix_user_home,
0777 & ~getdef_num ("UMASK", GETDEF_DEFAULT_UMASK)); 0777 & ~getdef_num ("UMASK", GETDEF_DEFAULT_UMASK));
home_added = true; home_added = true;
#ifdef WITH_AUDIT #ifdef WITH_AUDIT
@ -2007,7 +2082,10 @@ static void create_mail (void)
if (NULL == spool) { if (NULL == spool) {
spool = "/var/mail"; spool = "/var/mail";
} }
file = alloca (strlen (spool) + strlen (user_name) + 2); file = alloca (strlen (prefix) + strlen (spool) + strlen (user_name) + 2);
if(prefix[0])
sprintf (file, "%s/%s/%s", prefix, spool, user_name);
else
sprintf (file, "%s/%s", spool, user_name); sprintf (file, "%s/%s", spool, user_name);
fd = open (file, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0); fd = open (file, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0);
if (fd < 0) { if (fd < 0) {
@ -2015,7 +2093,7 @@ static void create_mail (void)
return; return;
} }
gr = getgrnam ("mail"); /* local, no need for xgetgrnam */ gr = prefix_getgrnam ("mail"); /* local, no need for xgetgrnam */
if (NULL == gr) { if (NULL == gr) {
fputs (_("Group 'mail' not found. Creating the user mailbox file with 0600 mode.\n"), fputs (_("Group 'mail' not found. Creating the user mailbox file with 0600 mode.\n"),
stderr); stderr);
@ -2064,6 +2142,8 @@ int main (int argc, char **argv)
process_root_flag ("-R", argc, argv); process_root_flag ("-R", argc, argv);
prefix = process_prefix_flag("-P", argc, argv);
OPENLOG ("useradd"); OPENLOG ("useradd");
#ifdef WITH_AUDIT #ifdef WITH_AUDIT
audit_help_open (); audit_help_open ();
@ -2147,7 +2227,7 @@ int main (int argc, char **argv)
/* /*
* Start with a quick check to see if the user exists. * Start with a quick check to see if the user exists.
*/ */
if (getpwnam (user_name) != NULL) { /* local, no need for xgetpwnam */ if (prefix_getpwnam (user_name) != NULL) { /* local, no need for xgetpwnam */
fprintf (stderr, _("%s: user '%s' already exists\n"), Prog, user_name); fprintf (stderr, _("%s: user '%s' already exists\n"), Prog, user_name);
#ifdef WITH_AUDIT #ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_USER, Prog, audit_logger (AUDIT_ADD_USER, Prog,
@ -2166,7 +2246,7 @@ int main (int argc, char **argv)
*/ */
if (Uflg) { if (Uflg) {
/* local, no need for xgetgrnam */ /* local, no need for xgetgrnam */
if (getgrnam (user_name) != NULL) { if (prefix_getgrnam (user_name) != NULL) {
fprintf (stderr, fprintf (stderr,
_("%s: group %s exists - if you want to add this user to that group, use -g.\n"), _("%s: group %s exists - if you want to add this user to that group, use -g.\n"),
Prog, user_name); Prog, user_name);
@ -2201,7 +2281,7 @@ int main (int argc, char **argv)
fail_exit (E_UID_IN_USE); fail_exit (E_UID_IN_USE);
} }
} else { } else {
if (getpwuid (user_id) != NULL) { if (prefix_getpwuid (user_id) != NULL) {
fprintf (stderr, fprintf (stderr,
_("%s: UID %lu is not unique\n"), _("%s: UID %lu is not unique\n"),
Prog, (unsigned long) user_id); Prog, (unsigned long) user_id);
@ -2264,7 +2344,7 @@ int main (int argc, char **argv)
if (mflg) { if (mflg) {
create_home (); create_home ();
if (home_added) { if (home_added) {
copy_tree (def_template, user_home, false, false, copy_tree (def_template, prefix_user_home, false, false,
(uid_t)-1, user_id, (gid_t)-1, user_gid); (uid_t)-1, user_id, (gid_t)-1, user_gid);
} else { } else {
fprintf (stderr, fprintf (stderr,

View File

@ -34,6 +34,7 @@
#ident "$Id$" #ident "$Id$"
#include <assert.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <getopt.h> #include <getopt.h>
@ -114,6 +115,8 @@ static bool sub_uid_locked = false;
static bool sub_gid_locked = false; static bool sub_gid_locked = false;
#endif /* ENABLE_SUBIDS */ #endif /* ENABLE_SUBIDS */
static const char* prefix = "";
/* local function prototypes */ /* local function prototypes */
static void usage (int status); static void usage (int status);
static void update_groups (void); static void update_groups (void);
@ -150,6 +153,7 @@ static void usage (int status)
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout); (void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
(void) fputs (_(" -r, --remove remove home directory and mail spool\n"), usageout); (void) fputs (_(" -r, --remove remove home directory and mail spool\n"), usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
(void) fputs (_(" -P, --prefix PREFIX_DIR prefix directory where are located the /etc/* files\n"), usageout);
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
(void) fputs (_(" -Z, --selinux-user remove any SELinux user mapping for the user\n"), usageout); (void) fputs (_(" -Z, --selinux-user remove any SELinux user mapping for the user\n"), usageout);
#endif /* WITH_SELINUX */ #endif /* WITH_SELINUX */
@ -327,8 +331,8 @@ static void remove_usergroup (void)
* Scan the passwd file to check if this group is still * Scan the passwd file to check if this group is still
* used as a primary group. * used as a primary group.
*/ */
setpwent (); prefix_setpwent ();
while ((pwd = getpwent ()) != NULL) { while ((pwd = prefix_getpwent ()) != NULL) {
if (strcmp (pwd->pw_name, user_name) == 0) { if (strcmp (pwd->pw_name, user_name) == 0) {
continue; continue;
} }
@ -339,7 +343,7 @@ static void remove_usergroup (void)
break; break;
} }
} }
endpwent (); prefix_endpwent ();
} }
if (NULL == pwd) { if (NULL == pwd) {
@ -815,9 +819,10 @@ static int is_owner (uid_t uid, const char *path)
static int remove_mailbox (void) static int remove_mailbox (void)
{ {
const char *maildir; const char *maildir;
char mailfile[1024]; char* mailfile;
int i; int i;
int errors = 0; int errors = 0;
size_t len;
maildir = getdef_str ("MAIL_DIR"); maildir = getdef_str ("MAIL_DIR");
#ifdef MAIL_SPOOL_DIR #ifdef MAIL_SPOOL_DIR
@ -828,13 +833,26 @@ static int remove_mailbox (void)
if (NULL == maildir) { if (NULL == maildir) {
return 0; return 0;
} }
snprintf (mailfile, sizeof mailfile, "%s/%s", maildir, user_name);
len = strlen (prefix) + strlen (maildir) + strlen (user_name) + 2;
mailfile = xmalloc (len);
if (prefix[0]) {
(void) snprintf (mailfile, len, "%s/%s/%s",
prefix, maildir, user_name);
}
else {
(void) snprintf (mailfile, len, "%s/%s",
maildir, user_name);
}
mailfile[len-1] = '\0';
if (access (mailfile, F_OK) != 0) { if (access (mailfile, F_OK) != 0) {
if (ENOENT == errno) { if (ENOENT == errno) {
fprintf (stderr, fprintf (stderr,
_("%s: %s mail spool (%s) not found\n"), _("%s: %s mail spool (%s) not found\n"),
Prog, user_name, mailfile); Prog, user_name, mailfile);
free(mailfile);
return 0; return 0;
} else { } else {
fprintf (stderr, fprintf (stderr,
@ -847,6 +865,7 @@ static int remove_mailbox (void)
user_name, (unsigned int) user_id, user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE); SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */ #endif /* WITH_AUDIT */
free(mailfile);
return -1; return -1;
} }
} }
@ -875,6 +894,7 @@ static int remove_mailbox (void)
SHADOW_AUDIT_SUCCESS); SHADOW_AUDIT_SUCCESS);
} }
#endif /* WITH_AUDIT */ #endif /* WITH_AUDIT */
free(mailfile);
return errors; return errors;
} }
i = is_owner (user_id, mailfile); i = is_owner (user_id, mailfile);
@ -891,8 +911,10 @@ static int remove_mailbox (void)
user_name, (unsigned int) user_id, user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE); SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */ #endif /* WITH_AUDIT */
free(mailfile);
return 1; return 1;
} else if (i == -1) { } else if (i == -1) {
free(mailfile);
return 0; /* mailbox doesn't exist */ return 0; /* mailbox doesn't exist */
} }
if (unlink (mailfile) != 0) { if (unlink (mailfile) != 0) {
@ -918,6 +940,7 @@ static int remove_mailbox (void)
SHADOW_AUDIT_SUCCESS); SHADOW_AUDIT_SUCCESS);
} }
#endif /* WITH_AUDIT */ #endif /* WITH_AUDIT */
free(mailfile);
return errors; return errors;
} }
@ -991,6 +1014,7 @@ int main (int argc, char **argv)
(void) textdomain (PACKAGE); (void) textdomain (PACKAGE);
process_root_flag ("-R", argc, argv); process_root_flag ("-R", argc, argv);
prefix = process_prefix_flag ("-P", argc, argv);
OPENLOG ("userdel"); OPENLOG ("userdel");
#ifdef WITH_AUDIT #ifdef WITH_AUDIT
@ -1007,6 +1031,7 @@ int main (int argc, char **argv)
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{"remove", no_argument, NULL, 'r'}, {"remove", no_argument, NULL, 'r'},
{"root", required_argument, NULL, 'R'}, {"root", required_argument, NULL, 'R'},
{"prefix", required_argument, NULL, 'P'},
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
{"selinux-user", no_argument, NULL, 'Z'}, {"selinux-user", no_argument, NULL, 'Z'},
#endif /* WITH_SELINUX */ #endif /* WITH_SELINUX */
@ -1014,9 +1039,9 @@ int main (int argc, char **argv)
}; };
while ((c = getopt_long (argc, argv, while ((c = getopt_long (argc, argv,
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
"fhrR:Z", "fhrR:P:Z",
#else /* !WITH_SELINUX */ #else /* !WITH_SELINUX */
"fhrR:", "fhrR:P:",
#endif /* !WITH_SELINUX */ #endif /* !WITH_SELINUX */
long_options, NULL)) != -1) { long_options, NULL)) != -1) {
switch (c) { switch (c) {
@ -1032,8 +1057,16 @@ int main (int argc, char **argv)
case 'R': /* no-op, handled in process_root_flag () */ case 'R': /* no-op, handled in process_root_flag () */
Rflg = true; Rflg = true;
break; break;
case 'P': /* no-op, handled in process_prefix_flag () */
break;
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
case 'Z': case 'Z':
if (prefix[0]) {
fprintf (stderr,
_("%s: -Z cannot be used with --prefix\n"),
Prog);
exit (E_BAD_ARG);
}
if (is_selinux_enabled () > 0) { if (is_selinux_enabled () > 0) {
Zflg = true; Zflg = true;
} else { } else {
@ -1123,7 +1156,18 @@ int main (int argc, char **argv)
} }
user_id = pwd->pw_uid; user_id = pwd->pw_uid;
user_gid = pwd->pw_gid; user_gid = pwd->pw_gid;
if(prefix[0]) {
size_t len = strlen(prefix) + strlen(pwd->pw_dir) + 2;
int wlen;
user_home = xmalloc(len);
wlen = snprintf(user_home, len, "%s/%s", prefix, pwd->pw_dir);
assert (wlen == (int) len -1);
}
else {
user_home = xstrdup (pwd->pw_dir); user_home = xstrdup (pwd->pw_dir);
}
pw_close(); pw_close();
} }
#ifdef WITH_TCB #ifdef WITH_TCB
@ -1156,7 +1200,7 @@ int main (int argc, char **argv)
* Note: This is a best effort basis. The user may log in between, * Note: This is a best effort basis. The user may log in between,
* a cron job may be started on her behalf, etc. * a cron job may be started on her behalf, etc.
*/ */
if (!Rflg && user_busy (user_name, user_id) != 0) { if ((prefix[0] == '\0') && !Rflg && user_busy (user_name, user_id) != 0) {
if (!fflg) { if (!fflg) {
#ifdef WITH_AUDIT #ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog, audit_logger (AUDIT_DEL_USER, Prog,
@ -1207,8 +1251,8 @@ int main (int argc, char **argv)
* prevent accidents if someone has /home or / as home * prevent accidents if someone has /home or / as home
* directory... --marekm * directory... --marekm
*/ */
setpwent (); prefix_setpwent ();
while ((pwd = getpwent ())) { while ((pwd = prefix_getpwent ())) {
if (strcmp (pwd->pw_name, user_name) == 0) { if (strcmp (pwd->pw_name, user_name) == 0) {
continue; continue;
} }
@ -1222,7 +1266,7 @@ int main (int argc, char **argv)
break; break;
} }
} }
endpwent (); prefix_endpwent ();
} }
#endif /* EXTRA_CHECK_HOME_DIR */ #endif /* EXTRA_CHECK_HOME_DIR */
@ -1274,6 +1318,7 @@ int main (int argc, char **argv)
* Cancel any crontabs or at jobs. Have to do this before we remove * Cancel any crontabs or at jobs. Have to do this before we remove
* the entry from /etc/passwd. * the entry from /etc/passwd.
*/ */
if(prefix[0] == '\0')
user_cancel (user_name); user_cancel (user_name);
close_files (); close_files ();

View File

@ -34,6 +34,7 @@
#ident "$Id$" #ident "$Id$"
#include <assert.h>
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
@ -124,6 +125,10 @@ static long user_newinactive;
static long sys_ngroups; static long sys_ngroups;
static char **user_groups; /* NULL-terminated list */ static char **user_groups; /* NULL-terminated list */
static const char* prefix = "";
static char* prefix_user_home = NULL;
static char* prefix_user_newhome = NULL;
static bool static bool
aflg = false, /* append to existing secondary group set */ aflg = false, /* append to existing secondary group set */
cflg = false, /* new comment (GECOS) field */ cflg = false, /* new comment (GECOS) field */
@ -264,7 +269,7 @@ static int get_groups (char *list)
* Names starting with digits are treated as numerical GID * Names starting with digits are treated as numerical GID
* values, otherwise the string is looked up as is. * values, otherwise the string is looked up as is.
*/ */
grp = getgr_nam_gid (list); grp = prefix_getgr_nam_gid (list);
/* /*
* There must be a match, either by GID value or by * There must be a match, either by GID value or by
@ -420,6 +425,7 @@ static /*@noreturn@*/void usage (int status)
(void) fputs (_(" -o, --non-unique allow using duplicate (non-unique) UID\n"), usageout); (void) fputs (_(" -o, --non-unique allow using duplicate (non-unique) UID\n"), usageout);
(void) fputs (_(" -p, --password PASSWORD use encrypted password for the new password\n"), usageout); (void) fputs (_(" -p, --password PASSWORD use encrypted password for the new password\n"), usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
(void) fputs (_(" -P, --prefix PREFIX_DIR prefix directory where are located the /etc/* files\n"), usageout);
(void) fputs (_(" -s, --shell SHELL new login shell for the user account\n"), usageout); (void) fputs (_(" -s, --shell SHELL new login shell for the user account\n"), usageout);
(void) fputs (_(" -u, --uid UID new UID for the user account\n"), usageout); (void) fputs (_(" -u, --uid UID new UID for the user account\n"), usageout);
(void) fputs (_(" -U, --unlock unlock the user account\n"), usageout); (void) fputs (_(" -U, --unlock unlock the user account\n"), usageout);
@ -997,6 +1003,7 @@ static void process_flags (int argc, char **argv)
{"non-unique", no_argument, NULL, 'o'}, {"non-unique", no_argument, NULL, 'o'},
{"password", required_argument, NULL, 'p'}, {"password", required_argument, NULL, 'p'},
{"root", required_argument, NULL, 'R'}, {"root", required_argument, NULL, 'R'},
{"prefix", required_argument, NULL, 'P'},
{"shell", required_argument, NULL, 's'}, {"shell", required_argument, NULL, 's'},
{"uid", required_argument, NULL, 'u'}, {"uid", required_argument, NULL, 'u'},
{"unlock", no_argument, NULL, 'U'}, {"unlock", no_argument, NULL, 'U'},
@ -1012,7 +1019,7 @@ static void process_flags (int argc, char **argv)
{NULL, 0, NULL, '\0'} {NULL, 0, NULL, '\0'}
}; };
while ((c = getopt_long (argc, argv, while ((c = getopt_long (argc, argv,
"ac:d:e:f:g:G:hl:Lmop:R:s:u:U" "ac:d:e:f:g:G:hl:Lmop:R:s:u:UP:"
#ifdef ENABLE_SUBIDS #ifdef ENABLE_SUBIDS
"v:w:V:W:" "v:w:V:W:"
#endif /* ENABLE_SUBIDS */ #endif /* ENABLE_SUBIDS */
@ -1114,6 +1121,8 @@ static void process_flags (int argc, char **argv)
break; break;
case 'R': /* no-op, handled in process_root_flag () */ case 'R': /* no-op, handled in process_root_flag () */
break; break;
case 'P': /* no-op, handled in process_prefix_flag () */
break;
case 's': case 's':
if (!VALID (optarg)) { if (!VALID (optarg)) {
fprintf (stderr, fprintf (stderr,
@ -1177,6 +1186,12 @@ static void process_flags (int argc, char **argv)
#endif /* ENABLE_SUBIDS */ #endif /* ENABLE_SUBIDS */
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
case 'Z': case 'Z':
if (prefix[0]) {
fprintf (stderr,
_("%s: -Z cannot be used with --prefix\n"),
Prog);
exit (E_BAD_ARG);
}
if (is_selinux_enabled () > 0) { if (is_selinux_enabled () > 0) {
user_selinux = optarg; user_selinux = optarg;
Zflg = true; Zflg = true;
@ -1204,7 +1219,7 @@ static void process_flags (int argc, char **argv)
{ {
const struct passwd *pwd; const struct passwd *pwd;
/* local, no need for xgetpwnam */ /* local, no need for xgetpwnam */
pwd = getpwnam (user_name); pwd = prefix_getpwnam (user_name);
if (NULL == pwd) { if (NULL == pwd) {
fprintf (stderr, fprintf (stderr,
_("%s: user '%s' does not exist\n"), _("%s: user '%s' does not exist\n"),
@ -1230,6 +1245,22 @@ static void process_flags (int argc, char **argv)
if (!gflg) { if (!gflg) {
user_newgid = user_gid; user_newgid = user_gid;
} }
if(prefix[0]) {
size_t len = strlen(prefix) + strlen(user_home) + 2;
int wlen;
prefix_user_home = xmalloc(len);
wlen = snprintf(prefix_user_home, len, "%s/%s", prefix, user_home);
assert (wlen == (int) len -1);
len = strlen(prefix) + strlen(user_newhome) + 2;
prefix_user_newhome = xmalloc(len);
wlen = snprintf(prefix_user_newhome, len, "%s/%s", prefix, user_newhome);
assert (wlen == (int) len -1);
}
else {
prefix_user_home = user_home;
prefix_user_newhome = user_newhome;
}
#ifdef USE_NIS #ifdef USE_NIS
/* /*
@ -1256,7 +1287,7 @@ static void process_flags (int argc, char **argv)
{ {
const struct spwd *spwd = NULL; const struct spwd *spwd = NULL;
/* local, no need for xgetspnam */ /* local, no need for xgetspnam */
if (is_shadow_pwd && ((spwd = getspnam (user_name)) != NULL)) { if (is_shadow_pwd && ((spwd = prefix_getspnam (user_name)) != NULL)) {
user_expire = spwd->sp_expire; user_expire = spwd->sp_expire;
user_inactive = spwd->sp_inact; user_inactive = spwd->sp_inact;
} }
@ -1346,7 +1377,7 @@ static void process_flags (int argc, char **argv)
} }
/* local, no need for xgetpwnam */ /* local, no need for xgetpwnam */
if (lflg && (getpwnam (user_newname) != NULL)) { if (lflg && (prefix_getpwnam (user_newname) != NULL)) {
fprintf (stderr, fprintf (stderr,
_("%s: user '%s' already exists\n"), _("%s: user '%s' already exists\n"),
Prog, user_newname); Prog, user_newname);
@ -1354,7 +1385,7 @@ static void process_flags (int argc, char **argv)
} }
/* local, no need for xgetpwuid */ /* local, no need for xgetpwuid */
if (uflg && !oflg && (getpwuid (user_newid) != NULL)) { if (uflg && !oflg && (prefix_getpwuid (user_newid) != NULL)) {
fprintf (stderr, fprintf (stderr,
_("%s: UID '%lu' already exists\n"), _("%s: UID '%lu' already exists\n"),
Prog, (unsigned long) user_newid); Prog, (unsigned long) user_newid);
@ -1731,7 +1762,7 @@ static void move_home (void)
{ {
struct stat sb; struct stat sb;
if (access (user_newhome, F_OK) == 0) { if (access (prefix_user_newhome, F_OK) == 0) {
/* /*
* If the new home directory already exist, the user * If the new home directory already exist, the user
* should not use -m. * should not use -m.
@ -1742,7 +1773,7 @@ static void move_home (void)
fail_exit (E_HOMEDIR); fail_exit (E_HOMEDIR);
} }
if (stat (user_home, &sb) == 0) { if (stat (prefix_user_home, &sb) == 0) {
/* /*
* Don't try to move it if it is not a directory * Don't try to move it if it is not a directory
* (but /dev/null for example). --marekm * (but /dev/null for example). --marekm
@ -1764,11 +1795,11 @@ static void move_home (void)
} }
#endif #endif
if (rename (user_home, user_newhome) == 0) { if (rename (prefix_user_home, prefix_user_newhome) == 0) {
/* FIXME: rename above may have broken symlinks /* FIXME: rename above may have broken symlinks
* pointing to the user's home directory * pointing to the user's home directory
* with an absolute path. */ * with an absolute path. */
if (chown_tree (user_newhome, if (chown_tree (prefix_user_newhome,
user_id, uflg ? user_newid : (uid_t)-1, user_id, uflg ? user_newid : (uid_t)-1,
user_gid, gflg ? user_newgid : (gid_t)-1) != 0) { user_gid, gflg ? user_newgid : (gid_t)-1) != 0) {
fprintf (stderr, fprintf (stderr,
@ -1785,16 +1816,16 @@ static void move_home (void)
return; return;
} else { } else {
if (EXDEV == errno) { if (EXDEV == errno) {
if (copy_tree (user_home, user_newhome, true, if (copy_tree (prefix_user_home, prefix_user_newhome, true,
true, true,
user_id, user_id,
uflg ? user_newid : (uid_t)-1, uflg ? user_newid : (uid_t)-1,
user_gid, user_gid,
gflg ? user_newgid : (gid_t)-1) == 0) { gflg ? user_newgid : (gid_t)-1) == 0) {
if (remove_tree (user_home, true) != 0) { if (remove_tree (prefix_user_home, true) != 0) {
fprintf (stderr, fprintf (stderr,
_("%s: warning: failed to completely remove old home directory %s"), _("%s: warning: failed to completely remove old home directory %s"),
Prog, user_home); Prog, prefix_user_home);
} }
#ifdef WITH_AUDIT #ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, audit_logger (AUDIT_USER_CHAUTHTOK,
@ -1807,11 +1838,11 @@ static void move_home (void)
return; return;
} }
(void) remove_tree (user_newhome, true); (void) remove_tree (prefix_user_newhome, true);
} }
fprintf (stderr, fprintf (stderr,
_("%s: cannot rename directory %s to %s\n"), _("%s: cannot rename directory %s to %s\n"),
Prog, user_home, user_newhome); Prog, prefix_user_home, prefix_user_newhome);
fail_exit (E_HOMEDIR); fail_exit (E_HOMEDIR);
} }
} }
@ -1949,9 +1980,11 @@ static void update_faillog (void)
static void move_mailbox (void) static void move_mailbox (void)
{ {
const char *maildir; const char *maildir;
char mailfile[1024], newmailfile[1024]; char* mailfile;
char* newmailfile;
int fd; int fd;
struct stat st; struct stat st;
size_t len;
maildir = getdef_str ("MAIL_DIR"); maildir = getdef_str ("MAIL_DIR");
#ifdef MAIL_SPOOL_DIR #ifdef MAIL_SPOOL_DIR
@ -1962,6 +1995,8 @@ static void move_mailbox (void)
if (NULL == maildir) { if (NULL == maildir) {
return; return;
} }
len = strlen (prefix) + strlen (maildir) + strlen (user_name) + 2;
mailfile = alloca (len);
/* /*
* O_NONBLOCK is to make sure open won't hang on mandatory locks. * O_NONBLOCK is to make sure open won't hang on mandatory locks.
@ -1969,9 +2004,16 @@ static void move_mailbox (void)
* replacing /var/spool/mail/luser with a hard link to /etc/passwd * replacing /var/spool/mail/luser with a hard link to /etc/passwd
* between stat and chown). --marekm * between stat and chown). --marekm
*/ */
(void) snprintf (mailfile, sizeof mailfile, "%s/%s", if (prefix[0]) {
(void) snprintf (mailfile, len, "%s/%s/%s",
prefix, maildir, user_name);
}
else {
(void) snprintf (mailfile, len, "%s/%s",
maildir, user_name); maildir, user_name);
mailfile[(sizeof mailfile) - 1] = '\0'; }
mailfile[len-1] = '\0';
fd = open (mailfile, O_RDONLY | O_NONBLOCK, 0); fd = open (mailfile, O_RDONLY | O_NONBLOCK, 0);
if (fd < 0) { if (fd < 0) {
/* no need for warnings if the mailbox doesn't exist */ /* no need for warnings if the mailbox doesn't exist */
@ -2008,9 +2050,17 @@ static void move_mailbox (void)
(void) close (fd); (void) close (fd);
if (lflg) { if (lflg) {
(void) snprintf (newmailfile, sizeof newmailfile, "%s/%s", len = strlen (prefix) + strlen (maildir) + strlen (user_newname) + 2;
newmailfile = alloca(len);
if (prefix[0]) {
(void) snprintf (newmailfile, len, "%s/%s/%s",
prefix, maildir, user_newname);
}
else {
(void) snprintf (newmailfile, len, "%s/%s",
maildir, user_newname); maildir, user_newname);
newmailfile[(sizeof newmailfile) - 1] = '\0'; }
newmailfile[len - 1] = '\0';
if ( (link (mailfile, newmailfile) != 0) if ( (link (mailfile, newmailfile) != 0)
|| (unlink (mailfile) != 0)) { || (unlink (mailfile) != 0)) {
perror (_("failed to rename mailbox")); perror (_("failed to rename mailbox"));
@ -2048,6 +2098,7 @@ int main (int argc, char **argv)
(void) textdomain (PACKAGE); (void) textdomain (PACKAGE);
process_root_flag ("-R", argc, argv); process_root_flag ("-R", argc, argv);
prefix = process_prefix_flag ("-P", argc, argv);
OPENLOG ("usermod"); OPENLOG ("usermod");
#ifdef WITH_AUDIT #ifdef WITH_AUDIT
@ -2072,8 +2123,9 @@ int main (int argc, char **argv)
/* /*
* The home directory, the username and the user's UID should not * The home directory, the username and the user's UID should not
* be changed while the user is logged in. * be changed while the user is logged in.
* Note: no need to check if a prefix is specified...
*/ */
if ( (uflg || lflg || dflg if ( (prefix[0] == '\0') && (uflg || lflg || dflg
#ifdef ENABLE_SUBIDS #ifdef ENABLE_SUBIDS
|| Vflg || Wflg || Vflg || Wflg
#endif /* ENABLE_SUBIDS */ #endif /* ENABLE_SUBIDS */
@ -2250,7 +2302,7 @@ int main (int argc, char **argv)
} }
if (!mflg && (uflg || gflg)) { if (!mflg && (uflg || gflg)) {
if (access (dflg ? user_newhome : user_home, F_OK) == 0) { if (access (dflg ? prefix_user_newhome : prefix_user_home, F_OK) == 0) {
/* /*
* Change the UID on all of the files owned by * Change the UID on all of the files owned by
* `user_id' to `user_newid' in the user's home * `user_id' to `user_newid' in the user's home
@ -2267,7 +2319,7 @@ int main (int argc, char **argv)
user_newname, (unsigned int) user_newid, 1); user_newname, (unsigned int) user_newid, 1);
} }
#endif #endif
if (chown_tree (dflg ? user_newhome : user_home, if (chown_tree (dflg ? prefix_user_newhome : prefix_user_home,
user_id, user_id,
uflg ? user_newid : (uid_t)-1, uflg ? user_newid : (uid_t)-1,
user_gid, user_gid,