Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d63956d640 | |||
| d5ecf56f23 | |||
| 514beca807 | |||
| 610b079510 | |||
| 118f9b53e3 | |||
| babbfd2ffb | |||
| d5616f4c4e | |||
| 79ce7adda3 | |||
| 7d974e3e9b | |||
| c53b76cc49 | |||
| ec00428f90 |
+11
@@ -15,4 +15,15 @@ SUBDIRS += man
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
CLEANFILES = man/8.out man/po/remove-potcdate.* man/*/login.defs.d man/*/*.mo
|
CLEANFILES = man/8.out man/po/remove-potcdate.* man/*/login.defs.d man/*/*.mo
|
||||||
|
|
||||||
EXTRA_DIST = tests/
|
EXTRA_DIST = tests/
|
||||||
|
|
||||||
|
dist-hook:
|
||||||
|
chmod -R u+w $(distdir)/tests
|
||||||
|
chmod u+w $(distdir)
|
||||||
|
mv $(distdir)/tests/unit $(distdir)/realunittest
|
||||||
|
mv $(distdir)/tests/tests $(distdir)/realtests
|
||||||
|
rm -rf $(distdir)/tests
|
||||||
|
mv $(distdir)/realtests $(distdir)/tests
|
||||||
|
rm -rf $(distdir)/tests/unit $(distdir)/tests/Makefile*
|
||||||
|
mv $(distdir)/realunittest $(distdir)/tests/unit
|
||||||
|
|||||||
+9
-2
@@ -1,10 +1,10 @@
|
|||||||
dnl Process this file with autoconf to produce a configure script.
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
AC_PREREQ([2.69])
|
AC_PREREQ([2.69])
|
||||||
m4_define([libsubid_abi_major], 5)
|
m4_define([libsubid_abi_major], 4)
|
||||||
m4_define([libsubid_abi_minor], 0)
|
m4_define([libsubid_abi_minor], 0)
|
||||||
m4_define([libsubid_abi_micro], 0)
|
m4_define([libsubid_abi_micro], 0)
|
||||||
m4_define([libsubid_abi], [libsubid_abi_major.libsubid_abi_minor.libsubid_abi_micro])
|
m4_define([libsubid_abi], [libsubid_abi_major.libsubid_abi_minor.libsubid_abi_micro])
|
||||||
AC_INIT([shadow], [4.16.0], [pkg-shadow-devel@lists.alioth.debian.org], [],
|
AC_INIT([shadow], [4.15.3], [pkg-shadow-devel@lists.alioth.debian.org], [],
|
||||||
[https://github.com/shadow-maint/shadow])
|
[https://github.com/shadow-maint/shadow])
|
||||||
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects tar-pax])
|
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects tar-pax])
|
||||||
AC_CONFIG_MACRO_DIRS([m4])
|
AC_CONFIG_MACRO_DIRS([m4])
|
||||||
@@ -159,6 +159,13 @@ fi])
|
|||||||
AC_DEFINE_UNQUOTED(PASSWD_PROGRAM, "$shadow_cv_passwd_dir/passwd",
|
AC_DEFINE_UNQUOTED(PASSWD_PROGRAM, "$shadow_cv_passwd_dir/passwd",
|
||||||
[Path to passwd program.])
|
[Path to passwd program.])
|
||||||
|
|
||||||
|
dnl XXX - quick hack, should disappear before anyone notices :).
|
||||||
|
dnl XXX - I just read the above message :).
|
||||||
|
if test "$ac_cv_func_ruserok" = "yes"; then
|
||||||
|
AC_DEFINE(RLOGIN, 1, [Define if login should support the -r flag for rlogind.])
|
||||||
|
AC_DEFINE(RUSEROK, 0, [Define to the ruserok() "success" return value (0 or 1).])
|
||||||
|
fi
|
||||||
|
|
||||||
AC_ARG_ENABLE(shadowgrp,
|
AC_ARG_ENABLE(shadowgrp,
|
||||||
[AS_HELP_STRING([--enable-shadowgrp], [enable shadow group support @<:@default=yes@:>@])],
|
[AS_HELP_STRING([--enable-shadowgrp], [enable shadow group support @<:@default=yes@:>@])],
|
||||||
[case "${enableval}" in
|
[case "${enableval}" in
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ libshadow_la_SOURCES = \
|
|||||||
pwdcheck.c \
|
pwdcheck.c \
|
||||||
pwmem.c \
|
pwmem.c \
|
||||||
remove_tree.c \
|
remove_tree.c \
|
||||||
|
rlogin.c \
|
||||||
root_flag.c \
|
root_flag.c \
|
||||||
run_part.h \
|
run_part.h \
|
||||||
run_part.c \
|
run_part.c \
|
||||||
|
|||||||
+10
-2
@@ -23,6 +23,7 @@
|
|||||||
#include "sizeof.h"
|
#include "sizeof.h"
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t csrand32(void);
|
||||||
static uint32_t csrand_uniform32(uint32_t n);
|
static uint32_t csrand_uniform32(uint32_t n);
|
||||||
static unsigned long csrand_uniform_slow(unsigned long n);
|
static unsigned long csrand_uniform_slow(unsigned long n);
|
||||||
|
|
||||||
@@ -97,6 +98,13 @@ csrand_interval(unsigned long min, unsigned long max)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
csrand32(void)
|
||||||
|
{
|
||||||
|
return csrand();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fast Random Integer Generation in an Interval
|
* Fast Random Integer Generation in an Interval
|
||||||
* ACM Transactions on Modeling and Computer Simulation 29 (1), 2019
|
* ACM Transactions on Modeling and Computer Simulation 29 (1), 2019
|
||||||
@@ -109,12 +117,12 @@ csrand_uniform32(uint32_t n)
|
|||||||
uint64_t r, mult;
|
uint64_t r, mult;
|
||||||
|
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
return csrand();
|
return csrand32();
|
||||||
|
|
||||||
bound = -n % n; // analogous to `2^32 % n`, since `x % y == (x-y) % y`
|
bound = -n % n; // analogous to `2^32 % n`, since `x % y == (x-y) % y`
|
||||||
|
|
||||||
do {
|
do {
|
||||||
r = csrand();
|
r = csrand32();
|
||||||
mult = r * n;
|
mult = r * n;
|
||||||
rem = mult; // analogous to `mult % 2^32`
|
rem = mult; // analogous to `mult % 2^32`
|
||||||
} while (rem < bound); // p = (2^32 % n) / 2^32; W.C.: n=2^31+1, p=0.5
|
} while (rem < bound); // p = (2^32 % n) / 2^32; W.C.: n=2^31+1, p=0.5
|
||||||
|
|||||||
@@ -131,11 +131,6 @@ void nss_init(const char *nsswitch_path) {
|
|||||||
fprintf(shadow_logfd, "%s did not provide @find_subid_owners@\n", libname);
|
fprintf(shadow_logfd, "%s did not provide @find_subid_owners@\n", libname);
|
||||||
goto close_lib;
|
goto close_lib;
|
||||||
}
|
}
|
||||||
subid_nss->free = dlsym(h, "shadow_subid_free");
|
|
||||||
if (!subid_nss->free) {
|
|
||||||
fprintf(shadow_logfd, "%s did not provide @subid_free@\n", libname);
|
|
||||||
goto close_lib;
|
|
||||||
}
|
|
||||||
subid_nss->handle = h;
|
subid_nss->handle = h;
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
|||||||
+4
-13
@@ -284,19 +284,6 @@ struct subid_nss_ops {
|
|||||||
*/
|
*/
|
||||||
enum subid_status (*find_subid_owners)(unsigned long id, enum subid_type id_type, uid_t **uids, int *count);
|
enum subid_status (*find_subid_owners)(unsigned long id, enum subid_type id_type, uid_t **uids, int *count);
|
||||||
|
|
||||||
/*
|
|
||||||
* nss_free: free a memory block allocated by a subid plugin.
|
|
||||||
*
|
|
||||||
* @ptr - a pointer to a memory block to deallocate
|
|
||||||
*
|
|
||||||
* Some routines of subid_nss_ops allocate memory which should be freed by
|
|
||||||
* caller after use. In order to deallocate that memory block, one should
|
|
||||||
* use this routine to release that memory. By default, this function
|
|
||||||
* pointer is set to free(3) for backward compatibility. However, it is
|
|
||||||
* strongly recommended to define this routine explicitly.
|
|
||||||
*/
|
|
||||||
void (*free)(void *ptr);
|
|
||||||
|
|
||||||
/* The dlsym handle to close */
|
/* The dlsym handle to close */
|
||||||
void *handle;
|
void *handle;
|
||||||
};
|
};
|
||||||
@@ -369,6 +356,10 @@ unsigned long csrand_interval (unsigned long min, unsigned long max);
|
|||||||
/* remove_tree.c */
|
/* remove_tree.c */
|
||||||
extern int remove_tree (const char *root, bool remove_root);
|
extern int remove_tree (const char *root, bool remove_root);
|
||||||
|
|
||||||
|
/* rlogin.c */
|
||||||
|
extern int do_rlogin(const char *remote_host, char *name, size_t namesize,
|
||||||
|
char *term, size_t termsize);
|
||||||
|
|
||||||
/* root_flag.c */
|
/* root_flag.c */
|
||||||
extern void process_root_flag (const char* short_opt, int argc, char **argv);
|
extern void process_root_flag (const char* short_opt, int argc, char **argv);
|
||||||
|
|
||||||
|
|||||||
+135
@@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
|
||||||
|
* SPDX-FileCopyrightText: 1996 - 1999, Marek Michałkiewicz
|
||||||
|
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
|
||||||
|
* SPDX-FileCopyrightText: 2007 - 2008, Nicolas François
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#ifdef RLOGIN
|
||||||
|
|
||||||
|
#ident "$Id$"
|
||||||
|
|
||||||
|
#include "prototypes.h"
|
||||||
|
#include "defines.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
|
#include "atoi/str2i.h"
|
||||||
|
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
int spd_name;
|
||||||
|
int spd_baud;
|
||||||
|
} speed_table[] =
|
||||||
|
{
|
||||||
|
{ B50, 50},
|
||||||
|
{ B75, 75},
|
||||||
|
{ B110, 110},
|
||||||
|
{ B134, 134},
|
||||||
|
{ B150, 150},
|
||||||
|
{ B200, 200},
|
||||||
|
{ B300, 300},
|
||||||
|
{ B600, 600},
|
||||||
|
{ B1200, 1200},
|
||||||
|
{ B1800, 1800},
|
||||||
|
{ B2400, 2400},
|
||||||
|
{ B4800, 4800},
|
||||||
|
{ B9600, 9600},
|
||||||
|
{ B19200, 19200},
|
||||||
|
{ B38400, 38400},
|
||||||
|
{ -1, -1}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_remote_string(char *buf, size_t size)
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
if (read (0, buf, 1) != 1) {
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if ('\0' == *buf) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
--size;
|
||||||
|
if (size > 0) {
|
||||||
|
++buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*NOTREACHED*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
do_rlogin(const char *remote_host, char *name, size_t namesize, char *term,
|
||||||
|
size_t termsize)
|
||||||
|
{
|
||||||
|
struct passwd *pwd;
|
||||||
|
char remote_name[32];
|
||||||
|
char *cp;
|
||||||
|
unsigned long remote_speed = 9600;
|
||||||
|
int speed_name = B9600;
|
||||||
|
int i;
|
||||||
|
TERMIO termio;
|
||||||
|
|
||||||
|
get_remote_string(remote_name, sizeof(remote_name));
|
||||||
|
get_remote_string(name, namesize);
|
||||||
|
get_remote_string(term, termsize);
|
||||||
|
|
||||||
|
cp = strchr (term, '/');
|
||||||
|
if (NULL != cp) {
|
||||||
|
*cp = '\0';
|
||||||
|
cp++;
|
||||||
|
|
||||||
|
if (str2ul(&remote_speed, cp) == -1)
|
||||||
|
remote_speed = 9600;
|
||||||
|
}
|
||||||
|
for (i = 0;
|
||||||
|
( (speed_table[i].spd_baud != remote_speed)
|
||||||
|
&& (speed_table[i].spd_name != -1));
|
||||||
|
i++);
|
||||||
|
|
||||||
|
if (-1 != speed_table[i].spd_name) {
|
||||||
|
speed_name = speed_table[i].spd_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Put the terminal in cooked mode with echo turned on.
|
||||||
|
*/
|
||||||
|
|
||||||
|
GTTY (0, &termio);
|
||||||
|
termio.c_iflag |= ICRNL | IXON;
|
||||||
|
termio.c_oflag |= OPOST | ONLCR;
|
||||||
|
termio.c_lflag |= ICANON | ECHO | ECHOE;
|
||||||
|
#ifdef CBAUD
|
||||||
|
termio.c_cflag = (termio.c_cflag & ~CBAUD) | speed_name;
|
||||||
|
#else
|
||||||
|
termio.c_cflag = (termio.c_cflag) | speed_name;
|
||||||
|
#endif
|
||||||
|
STTY (0, &termio);
|
||||||
|
|
||||||
|
pwd = getpwnam (name); /* local, no need for xgetpwnam */
|
||||||
|
if (NULL == pwd) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ruserok() returns 0 for success on modern systems, and 1 on
|
||||||
|
* older ones. If you are having trouble with people logging
|
||||||
|
* in without giving a required password, THIS is the culprit -
|
||||||
|
* go fix the #define in config.h.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RUSEROK
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
return ruserok (remote_host, pwd->pw_uid == 0,
|
||||||
|
remote_name, name) == RUSEROK;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif /* RLOGIN */
|
||||||
+59
-43
@@ -274,40 +274,8 @@ static const struct subordinate_range *find_range(struct commonio_db *db,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* have_range: check whether @owner is authorized to use the range
|
|
||||||
* (@start .. @start+@count-1).
|
|
||||||
* @db: database to check
|
|
||||||
* @owner: owning uid being queried
|
|
||||||
* @start: start of range
|
|
||||||
* @count: number of uids in range
|
|
||||||
*
|
|
||||||
* Returns true if @owner is authorized to use the range, false otherwise.
|
|
||||||
*/
|
|
||||||
static bool have_range(struct commonio_db *db,
|
static bool have_range(struct commonio_db *db,
|
||||||
const char *owner, unsigned long start, unsigned long count)
|
const char *owner, unsigned long start, unsigned long count);
|
||||||
{
|
|
||||||
const struct subordinate_range *range;
|
|
||||||
unsigned long end;
|
|
||||||
|
|
||||||
if (count == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
end = start + count - 1;
|
|
||||||
range = find_range (db, owner, start);
|
|
||||||
while (range) {
|
|
||||||
unsigned long last;
|
|
||||||
|
|
||||||
last = range->start + range->count - 1;
|
|
||||||
if (last >= (start + count - 1))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
count = end - last;
|
|
||||||
start = last + 1;
|
|
||||||
range = find_range(db, owner, start);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool append_range(struct subid_range **ranges, const struct subordinate_range *new, int n)
|
static bool append_range(struct subid_range **ranges, const struct subordinate_range *new, int n)
|
||||||
{
|
{
|
||||||
@@ -574,6 +542,64 @@ static struct commonio_db subordinate_uid_db = {
|
|||||||
false /* setname */
|
false /* setname */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* have_range: check whether @owner is authorized to use the range
|
||||||
|
* (@start .. @start+@count-1).
|
||||||
|
* @db: database to check
|
||||||
|
* @owner: owning uid being queried
|
||||||
|
* @start: start of range
|
||||||
|
* @count: number of uids in range
|
||||||
|
*
|
||||||
|
* Returns true if @owner is authorized to use the range, false otherwise.
|
||||||
|
*/
|
||||||
|
static bool have_range(struct commonio_db *db,
|
||||||
|
const char *owner, unsigned long start, unsigned long count)
|
||||||
|
{
|
||||||
|
const struct subordinate_range *range;
|
||||||
|
unsigned long end;
|
||||||
|
bool doclose = false;
|
||||||
|
bool ret = false;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!db->isopen) {
|
||||||
|
doclose = true;
|
||||||
|
if (db == &subordinate_uid_db)
|
||||||
|
rc = sub_uid_open(O_RDONLY);
|
||||||
|
else
|
||||||
|
rc = sub_gid_open(O_RDONLY);
|
||||||
|
if (rc < 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
end = start + count - 1;
|
||||||
|
range = find_range (db, owner, start);
|
||||||
|
while (range) {
|
||||||
|
unsigned long last;
|
||||||
|
|
||||||
|
last = range->start + range->count - 1;
|
||||||
|
if (last >= (start + count - 1)) {
|
||||||
|
ret = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
count = end - last;
|
||||||
|
start = last + 1;
|
||||||
|
range = find_range(db, owner, start);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doclose) {
|
||||||
|
if (db == &subordinate_uid_db)
|
||||||
|
sub_uid_close();
|
||||||
|
else
|
||||||
|
sub_gid_close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int sub_uid_setdbname (const char *filename)
|
int sub_uid_setdbname (const char *filename)
|
||||||
{
|
{
|
||||||
return commonio_setname (&subordinate_uid_db, filename);
|
return commonio_setname (&subordinate_uid_db, filename);
|
||||||
@@ -1117,16 +1143,6 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_subid_pointer(void *ptr)
|
|
||||||
{
|
|
||||||
struct subid_nss_ops *h = get_subid_nss_handle();
|
|
||||||
if (h) {
|
|
||||||
h->free(ptr);
|
|
||||||
} else {
|
|
||||||
free(ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* !ENABLE_SUBIDS */
|
#else /* !ENABLE_SUBIDS */
|
||||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
extern int ISO_C_forbids_an_empty_translation_unit;
|
||||||
#endif /* !ENABLE_SUBIDS */
|
#endif /* !ENABLE_SUBIDS */
|
||||||
|
|||||||
@@ -43,9 +43,6 @@ extern int sub_gid_unlock (void);
|
|||||||
extern int sub_gid_add (const char *owner, gid_t start, unsigned long count);
|
extern int sub_gid_add (const char *owner, gid_t start, unsigned long count);
|
||||||
extern int sub_gid_remove (const char *owner, gid_t start, unsigned long count);
|
extern int sub_gid_remove (const char *owner, gid_t start, unsigned long count);
|
||||||
extern uid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count);
|
extern uid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count);
|
||||||
|
|
||||||
extern void free_subid_pointer(void *ptr);
|
|
||||||
|
|
||||||
#endif /* ENABLE_SUBIDS */
|
#endif /* ENABLE_SUBIDS */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -42,11 +42,6 @@ bool subid_init(const char *progname, FILE * logfd)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void subid_free(void *ptr)
|
|
||||||
{
|
|
||||||
free_subid_pointer(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int get_subid_ranges(const char *owner, enum subid_type id_type, struct subid_range **ranges)
|
int get_subid_ranges(const char *owner, enum subid_type id_type, struct subid_range **ranges)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -55,19 +55,6 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
bool subid_init(const char *progname, FILE *logfd);
|
bool subid_init(const char *progname, FILE *logfd);
|
||||||
|
|
||||||
/*
|
|
||||||
* subid_free: free memory allocated in any subid_* function
|
|
||||||
*
|
|
||||||
* @ptr: Pointer to a memory block to release.
|
|
||||||
*
|
|
||||||
* Some functions like @subid_get_uid_ranges allocate memory internally. As
|
|
||||||
* soon as a result is no longer needed, it should be freed with this routine.
|
|
||||||
* Initially, default function `free()` was used. Thus for backward
|
|
||||||
* compatibility this function falls back to `free()` if a plugin does not
|
|
||||||
* explicitly specify routine to free allocated memory.
|
|
||||||
*/
|
|
||||||
void subid_free(void *ptr);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* subid_get_uid_ranges: return a list of UID ranges for a user
|
* subid_get_uid_ranges: return a list of UID ranges for a user
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -215,6 +215,14 @@
|
|||||||
<para>Preserve environment.</para>
|
<para>Preserve environment.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>-r</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>Perform autologin protocol for rlogin.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ lib/pwdcheck.c
|
|||||||
lib/pwio.c
|
lib/pwio.c
|
||||||
lib/pwmem.c
|
lib/pwmem.c
|
||||||
lib/remove_tree.c
|
lib/remove_tree.c
|
||||||
|
lib/rlogin.c
|
||||||
lib/root_flag.c
|
lib/root_flag.c
|
||||||
lib/salt.c
|
lib/salt.c
|
||||||
lib/selinux.c
|
lib/selinux.c
|
||||||
|
|||||||
+1
-1
@@ -44,6 +44,6 @@ int main(int argc, char *argv[])
|
|||||||
printf("%d: %s %lu %lu\n", i, owner,
|
printf("%d: %s %lu %lu\n", i, owner,
|
||||||
ranges[i].start, ranges[i].count);
|
ranges[i].start, ranges[i].count);
|
||||||
}
|
}
|
||||||
subid_free(ranges);
|
free(ranges);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+71
-12
@@ -85,6 +85,11 @@ static struct lastlog ll;
|
|||||||
static bool pflg = false;
|
static bool pflg = false;
|
||||||
static bool fflg = false;
|
static bool fflg = false;
|
||||||
|
|
||||||
|
#ifdef RLOGIN
|
||||||
|
static bool rflg = false;
|
||||||
|
#else /* RLOGIN */
|
||||||
|
#define rflg false
|
||||||
|
#endif /* !RLOGIN */
|
||||||
static bool hflg = false;
|
static bool hflg = false;
|
||||||
static bool preauth_flag = false;
|
static bool preauth_flag = false;
|
||||||
|
|
||||||
@@ -129,6 +134,7 @@ static void exit_handler (int);
|
|||||||
* usage - print login command usage and exit
|
* usage - print login command usage and exit
|
||||||
*
|
*
|
||||||
* login [ name ]
|
* login [ name ]
|
||||||
|
* login -r hostname (for rlogind)
|
||||||
* login -h hostname (for telnetd, etc.)
|
* login -h hostname (for telnetd, etc.)
|
||||||
* login -f name (for pre-authenticated login: datakit, xterm, etc.)
|
* login -f name (for pre-authenticated login: datakit, xterm, etc.)
|
||||||
*/
|
*/
|
||||||
@@ -139,6 +145,9 @@ static void usage (void)
|
|||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
fprintf (stderr, _(" %s [-p] [-h host] [-f name]\n"), Prog);
|
fprintf (stderr, _(" %s [-p] [-h host] [-f name]\n"), Prog);
|
||||||
|
#ifdef RLOGIN
|
||||||
|
fprintf (stderr, _(" %s [-p] -r host\n"), Prog);
|
||||||
|
#endif /* RLOGIN */
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,7 +271,7 @@ static void process_flags (int argc, char *const *argv)
|
|||||||
/*
|
/*
|
||||||
* Check the flags for proper form. Every argument starting with
|
* Check the flags for proper form. Every argument starting with
|
||||||
* "-" must be exactly two characters long. This closes all the
|
* "-" must be exactly two characters long. This closes all the
|
||||||
* clever telnet, and getty holes.
|
* clever rlogin, telnet, and getty holes.
|
||||||
*/
|
*/
|
||||||
for (arg = 1; arg < argc; arg++) {
|
for (arg = 1; arg < argc; arg++) {
|
||||||
if (argv[arg][0] == '-' && strlen (argv[arg]) > 2) {
|
if (argv[arg][0] == '-' && strlen (argv[arg]) > 2) {
|
||||||
@@ -289,6 +298,13 @@ static void process_flags (int argc, char *const *argv)
|
|||||||
hostname = optarg;
|
hostname = optarg;
|
||||||
reason = PW_TELNET;
|
reason = PW_TELNET;
|
||||||
break;
|
break;
|
||||||
|
#ifdef RLOGIN
|
||||||
|
case 'r':
|
||||||
|
rflg = true;
|
||||||
|
hostname = optarg;
|
||||||
|
reason = PW_RLOGIN;
|
||||||
|
break;
|
||||||
|
#endif /* RLOGIN */
|
||||||
case 'p':
|
case 'p':
|
||||||
pflg = true;
|
pflg = true;
|
||||||
break;
|
break;
|
||||||
@@ -297,11 +313,21 @@ static void process_flags (int argc, char *const *argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef RLOGIN
|
||||||
|
/*
|
||||||
|
* Neither -h nor -f should be combined with -r.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (rflg && (hflg || fflg)) {
|
||||||
|
usage ();
|
||||||
|
}
|
||||||
|
#endif /* RLOGIN */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allow authentication bypass only if real UID is zero.
|
* Allow authentication bypass only if real UID is zero.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((fflg || hflg) && !amroot) {
|
if ((rflg || fflg || hflg) && !amroot) {
|
||||||
fprintf (stderr, _("%s: Permission denied.\n"), Prog);
|
fprintf (stderr, _("%s: Permission denied.\n"), Prog);
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
@@ -316,6 +342,11 @@ static void process_flags (int argc, char *const *argv)
|
|||||||
++optind;
|
++optind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef RLOGIN
|
||||||
|
if (rflg && (NULL != username)) {
|
||||||
|
usage ();
|
||||||
|
}
|
||||||
|
#endif /* RLOGIN */
|
||||||
if (fflg && (NULL == username)) {
|
if (fflg && (NULL == username)) {
|
||||||
usage ();
|
usage ();
|
||||||
}
|
}
|
||||||
@@ -443,6 +474,7 @@ static /*@observer@*/const char *get_failent_user (/*@returned@*/const char *use
|
|||||||
* the flags which login supports are
|
* the flags which login supports are
|
||||||
*
|
*
|
||||||
* -p - preserve the environment
|
* -p - preserve the environment
|
||||||
|
* -r - perform autologin protocol for rlogin
|
||||||
* -f - do not perform authentication, user is preauthenticated
|
* -f - do not perform authentication, user is preauthenticated
|
||||||
* -h - the name of the remote host
|
* -h - the name of the remote host
|
||||||
*/
|
*/
|
||||||
@@ -473,6 +505,9 @@ int main (int argc, char **argv)
|
|||||||
# if defined(ENABLE_LASTLOG)
|
# if defined(ENABLE_LASTLOG)
|
||||||
char ptime[80];
|
char ptime[80];
|
||||||
# endif
|
# endif
|
||||||
|
#endif
|
||||||
|
#if defined(RLOGIN)
|
||||||
|
char term[128] = "";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -524,7 +559,7 @@ int main (int argc, char **argv)
|
|||||||
is_console = console (tty);
|
is_console = console (tty);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (hflg) {
|
if (rflg || hflg) {
|
||||||
/*
|
/*
|
||||||
* Add remote hostname to the environment. I think
|
* Add remote hostname to the environment. I think
|
||||||
* (not sure) I saw it once on Irix. --marekm
|
* (not sure) I saw it once on Irix. --marekm
|
||||||
@@ -537,6 +572,23 @@ int main (int argc, char **argv)
|
|||||||
if (hflg) {
|
if (hflg) {
|
||||||
reason = PW_RLOGIN;
|
reason = PW_RLOGIN;
|
||||||
}
|
}
|
||||||
|
#ifdef RLOGIN
|
||||||
|
if (rflg) {
|
||||||
|
size_t max_size;
|
||||||
|
|
||||||
|
max_size = login_name_max_size();
|
||||||
|
assert (NULL == username);
|
||||||
|
username = XMALLOC(max_size, char);
|
||||||
|
username[max_size - 1] = '\0';
|
||||||
|
if (do_rlogin(hostname, username, max_size, term, sizeof(term)))
|
||||||
|
{
|
||||||
|
preauth_flag = true;
|
||||||
|
} else {
|
||||||
|
free (username);
|
||||||
|
username = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* RLOGIN */
|
||||||
|
|
||||||
OPENLOG (Prog);
|
OPENLOG (Prog);
|
||||||
|
|
||||||
@@ -571,11 +623,18 @@ int main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* preserve TERM from getty */
|
#ifdef RLOGIN
|
||||||
if (!pflg) {
|
if (term[0] != '\0') {
|
||||||
tmp = getenv ("TERM");
|
addenv ("TERM", term);
|
||||||
if (NULL != tmp) {
|
} else
|
||||||
addenv ("TERM", tmp);
|
#endif /* RLOGIN */
|
||||||
|
{
|
||||||
|
/* preserve TERM from getty */
|
||||||
|
if (!pflg) {
|
||||||
|
tmp = getenv ("TERM");
|
||||||
|
if (NULL != tmp) {
|
||||||
|
addenv ("TERM", tmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -585,7 +644,7 @@ int main (int argc, char **argv)
|
|||||||
set_env (argc - optind, &argv[optind]);
|
set_env (argc - optind, &argv[optind]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hflg) {
|
if (rflg || hflg) {
|
||||||
cp = hostname;
|
cp = hostname;
|
||||||
} else if ((host != NULL) && (host[0] != '\0')) {
|
} else if ((host != NULL) && (host[0] != '\0')) {
|
||||||
cp = host;
|
cp = host;
|
||||||
@@ -895,7 +954,7 @@ int main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The -f flag provides a name which has already
|
* The -r and -f flags provide a name which has already
|
||||||
* been authenticated by some server.
|
* been authenticated by some server.
|
||||||
*/
|
*/
|
||||||
if (preauth_flag) {
|
if (preauth_flag) {
|
||||||
@@ -984,8 +1043,8 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
(void) puts (_("Login incorrect"));
|
(void) puts (_("Login incorrect"));
|
||||||
|
|
||||||
/* allow only one attempt with -f */
|
/* allow only one attempt with -r or -f */
|
||||||
if (fflg || (retries <= 0)) {
|
if (rflg || fflg || (retries <= 0)) {
|
||||||
closelog ();
|
closelog ();
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|||||||
Executable
+61
@@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/expect -f
|
||||||
|
|
||||||
|
# This is a script for repeatedly logging into the localhost
|
||||||
|
# using `rlogin` in order to apparently see a symptoms described
|
||||||
|
# in bug #332198.
|
||||||
|
# As described in the bug log, sometimes `rlogind` will fail to
|
||||||
|
# establish a connection, because it starts "login" process and
|
||||||
|
# the latter fails with "unable to determine TTY name, got /dev/pts/1"
|
||||||
|
# message.
|
||||||
|
#
|
||||||
|
# BUGS
|
||||||
|
#
|
||||||
|
# * the script rlogins to localhost
|
||||||
|
# * the script doesn't handle passwdord prompt, because it's intended
|
||||||
|
# to use .rhosts auth and expects shell prompt immediately after
|
||||||
|
# `rlogin`
|
||||||
|
# * the regexp for shell prompt is hardcoded
|
||||||
|
|
||||||
|
log_user 0
|
||||||
|
match_max 8192
|
||||||
|
|
||||||
|
while {1} {
|
||||||
|
set rlogin_spawn [spawn rlogin localhost]
|
||||||
|
if { $rlogin_spawn == 0 } { exit 1 }
|
||||||
|
expect {
|
||||||
|
-timeout 10 -re "^.*(Last login\[^\r\n\]*).*\n(\[^\r\n\]*\[#$\] )$" {
|
||||||
|
send_error "$expect_out(1,string)\n"
|
||||||
|
send_error "$expect_out(2,string)\n"
|
||||||
|
# send_error "$expect_out(0,string)\n"
|
||||||
|
}
|
||||||
|
timeout {
|
||||||
|
send_error "TIMEOUT/prompt\n"
|
||||||
|
send_error "$expect_out(buffer)\n"
|
||||||
|
send_error "RETRYING\n"
|
||||||
|
log_user 1
|
||||||
|
send "tty /\r"
|
||||||
|
expect -timeout 2 -re "^.*\r?\n(\[^\r\n\]*# )$" {}
|
||||||
|
send "tty /\r"
|
||||||
|
expect -timeout 2 -re "^.*\r?\n(\[^\r\n\]*# )$" {}
|
||||||
|
send_error "\n"
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
send "tty\r"
|
||||||
|
expect {
|
||||||
|
-timeout 4 -re "tty\r?\n(\[^\r\n\]*)\r?\n(\[^\r\n\]*\[#$\] )$" {
|
||||||
|
send_error "$expect_out(2,string)$expect_out(1,string)\n"
|
||||||
|
# send_error "$expect_out(0,string)\n"
|
||||||
|
}
|
||||||
|
timeout { send_error "TIMEOUT/tty\n" ; exit 3 }
|
||||||
|
}
|
||||||
|
send "exit\r"
|
||||||
|
expect {
|
||||||
|
-timeout 2 eof {
|
||||||
|
# send_error "OK4: EOF\n"
|
||||||
|
}
|
||||||
|
timeout { send_error "TIMEOUT/eof\n" ; exit 4 }
|
||||||
|
}
|
||||||
|
wait
|
||||||
|
}
|
||||||
|
# vi: set sw=4:
|
||||||
@@ -2,14 +2,16 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
build_path=$(pwd)
|
if [ -n "${BUILD_BASE_DIR}" ]; then
|
||||||
while [ "${build_path}" != "/" -a ! -e "${build_path}/.git" ]; do
|
build_path="${BUILD_BASE_DIR}"
|
||||||
build_path=$(dirname ${build_path})
|
else
|
||||||
done
|
build_path=$(git rev-parse --show-toplevel)
|
||||||
if [ ! -e "${build_path}/.git" ]; then
|
|
||||||
echo "Not inside git directory" 1>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
if [ -z "${build_path}" ]; then
|
||||||
|
echo "Failed to find build base path"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
export build_path
|
||||||
|
|
||||||
# Save the configuration files in tmp.
|
# Save the configuration files in tmp.
|
||||||
save_config ()
|
save_config ()
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
all: test_nss libsubid_zzz.so
|
all: test_nss libsubid_zzz.so
|
||||||
|
|
||||||
test_nss: test_nss.c ../../../lib/nss.c
|
BASE_TEST_DIR ?= $(shell git rev-parse --show-toplevel)
|
||||||
gcc -c -I../../../lib/ -I../../.. -o test_nss.o test_nss.c
|
basedir := $(BASE_TEST_DIR)
|
||||||
gcc -o test_nss test_nss.o ../../../lib/.libs/libshadow.a -ldl
|
|
||||||
|
test_nss: test_nss.c $(basedir)/lib/nss.c
|
||||||
|
gcc -c -I$(basedir)/lib/ -I$(basedir) -o test_nss.o test_nss.c
|
||||||
|
gcc -o test_nss test_nss.o $(basedir)/lib/.libs/libshadow.a -ldl
|
||||||
|
|
||||||
libsubid_zzz.so: libsubid_zzz.c
|
libsubid_zzz.so: libsubid_zzz.c
|
||||||
gcc -c -I../../../lib/ -I../../.. -I../../../libsubid libsubid_zzz.c
|
gcc -c -I$(basedir)/lib/ -I$(basedir) -I$(basedir)/libsubid libsubid_zzz.c
|
||||||
gcc -L../../../libsubid -shared -o libsubid_zzz.so libsubid_zzz.o ../../../lib/.libs/libshadow.a -ldl
|
gcc -L$(basedir)/libsubid -shared -o libsubid_zzz.so libsubid_zzz.o $(basedir)/lib/.libs/libshadow.a -ldl
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o *.so test_nss
|
rm -f *.o *.so test_nss
|
||||||
|
|||||||
@@ -138,8 +138,3 @@ enum subid_status shadow_subid_list_owner_ranges(const char *owner, enum subid_t
|
|||||||
|
|
||||||
return SUBID_STATUS_SUCCESS;
|
return SUBID_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void shadow_subid_free(void *ptr)
|
|
||||||
{
|
|
||||||
free(ptr);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ cd $(dirname $0)
|
|||||||
|
|
||||||
make
|
make
|
||||||
|
|
||||||
export LD_LIBRARY_PATH=.:../../../lib/.libs:$LD_LIBRARY_PATH
|
export LD_LIBRARY_PATH=.:${build_path}/lib/.libs:$LD_LIBRARY_PATH
|
||||||
|
|
||||||
./test_nss 1
|
./test_nss 1
|
||||||
./test_nss 2
|
./test_nss 2
|
||||||
|
|||||||
@@ -11,23 +11,23 @@ cleanup1() {
|
|||||||
umount /etc/nsswitch.conf
|
umount /etc/nsswitch.conf
|
||||||
}
|
}
|
||||||
trap cleanup1 EXIT HUP INT TERM
|
trap cleanup1 EXIT HUP INT TERM
|
||||||
../../../src/check_subid_range user1 u 100000 65535
|
${build_path}/src/check_subid_range user1 u 100000 65535
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
../../../src/check_subid_range user2 u 100000 65535
|
${build_path}/src/check_subid_range user2 u 100000 65535
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
../../../src/check_subid_range unknown u 100000 65535
|
${build_path}/src/check_subid_range unknown u 100000 65535
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
../../../src/check_subid_range error u 100000 65535
|
${build_path}/src/check_subid_range error u 100000 65535
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
../../../src/check_subid_range user1 u 1000 65535
|
${build_path}/src/check_subid_range user1 u 1000 65535
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -43,7 +43,7 @@ cleanup2() {
|
|||||||
umount /etc/nsswitch.conf
|
umount /etc/nsswitch.conf
|
||||||
}
|
}
|
||||||
trap cleanup2 EXIT HUP INT TERM
|
trap cleanup2 EXIT HUP INT TERM
|
||||||
../../../src/check_subid_range user1 u 100000 65535
|
${build_path}/src/check_subid_range user1 u 100000 65535
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -7,6 +7,22 @@ unset LANG
|
|||||||
unset LANGUAGE
|
unset LANGUAGE
|
||||||
. common/config.sh
|
. common/config.sh
|
||||||
|
|
||||||
|
# When we unshare -Ur, we must be able to descend the build path.
|
||||||
|
# But $HOME might not be world x. Fix that.
|
||||||
|
fixup_home_perms() {
|
||||||
|
p="${build_path}"
|
||||||
|
d=""
|
||||||
|
echo "$p" | tr '/' '\n' | while read f; do
|
||||||
|
if [ -z "$f" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
d="$d/$f"
|
||||||
|
chmod ugo+x "$d"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
fixup_home_perms
|
||||||
|
|
||||||
USE_PAM="yes"
|
USE_PAM="yes"
|
||||||
FAILURE_TESTS="yes"
|
FAILURE_TESTS="yes"
|
||||||
|
|
||||||
|
|||||||
+31
-21
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -28,13 +29,29 @@
|
|||||||
static jmp_buf jmpb;
|
static jmp_buf jmpb;
|
||||||
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* WRAPPERS
|
|
||||||
**********************/
|
|
||||||
int __real_vasprintf(char **restrict p, const char *restrict fmt, va_list ap);
|
int __real_vasprintf(char **restrict p, const char *restrict fmt, va_list ap);
|
||||||
int __wrap_vasprintf(char **restrict p, const char *restrict fmt, va_list ap);
|
int __wrap_vasprintf(char **restrict p, const char *restrict fmt, va_list ap);
|
||||||
void __wrap_exit(int status);
|
void __wrap_exit(int status);
|
||||||
|
|
||||||
|
[[gnu::noipa]]
|
||||||
|
static int xasprintf_volatile(char *volatile *restrict s,
|
||||||
|
const char *restrict fmt, ...);
|
||||||
|
|
||||||
|
static void test_xasprintf_exit(void **state);
|
||||||
|
static void test_xasprintf_ok(void **state);
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
const struct CMUnitTest tests[] = {
|
||||||
|
cmocka_unit_test(test_xasprintf_exit),
|
||||||
|
cmocka_unit_test(test_xasprintf_ok),
|
||||||
|
};
|
||||||
|
|
||||||
|
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
__wrap_vasprintf(char **restrict p, const char *restrict fmt, va_list ap)
|
__wrap_vasprintf(char **restrict p, const char *restrict fmt, va_list ap)
|
||||||
@@ -50,11 +67,16 @@ __wrap_exit(int status)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************
|
static int
|
||||||
* TEST
|
xasprintf_volatile(char *volatile *restrict s, const char *restrict fmt, ...)
|
||||||
**********************/
|
{
|
||||||
static void test_xasprintf_exit(void **state);
|
int len;
|
||||||
static void test_xasprintf_ok(void **state);
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
len = xvasprintf((char **) s, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -70,7 +92,7 @@ test_xasprintf_exit(void **state)
|
|||||||
switch (setjmp(jmpb)) {
|
switch (setjmp(jmpb)) {
|
||||||
case 0:
|
case 0:
|
||||||
len = XASPRINTF_CALLED;
|
len = XASPRINTF_CALLED;
|
||||||
len = xasprintf(&p, "foo%s", "bar");
|
len = xasprintf_volatile(&p, "foo%s", "bar");
|
||||||
assert_unreachable();
|
assert_unreachable();
|
||||||
break;
|
break;
|
||||||
case EXIT_CALLED:
|
case EXIT_CALLED:
|
||||||
@@ -100,15 +122,3 @@ test_xasprintf_ok(void **state)
|
|||||||
assert_string_equal(p, "foo1bar");
|
assert_string_equal(p, "foo1bar");
|
||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
main(void)
|
|
||||||
{
|
|
||||||
const struct CMUnitTest tests[] = {
|
|
||||||
cmocka_unit_test(test_xasprintf_exit),
|
|
||||||
cmocka_unit_test(test_xasprintf_ok),
|
|
||||||
};
|
|
||||||
|
|
||||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user