From 1d336d3a1e77034fec0cfd59ba91e9d1e5ac157b Mon Sep 17 00:00:00 2001 From: nekral-guest Date: Sat, 28 Aug 2010 19:58:00 +0000 Subject: [PATCH] * lib/protoypes.h, libmisc/copydir.c, src/useradd.c: selinux_file_context renamed set_selinux_file_context. * lib/protoypes.h, libmisc/copydir.c, src/useradd.c: Added reset_selinux_file_context. * src/useradd.c: Check the return value of set_selinux_file_context and reset_selinux_file_context. * libmisc/copydir.c: Check the return value of reset_selinux_file_context. --- ChangeLog | 11 +++++++++ lib/prototypes.h | 3 ++- libmisc/copydir.c | 59 +++++++++++++++++++++++++++++++++++------------ src/useradd.c | 8 +++++-- 4 files changed, 63 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9d8adf86..95db96d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-08-28 Nicolas François + + * lib/protoypes.h, libmisc/copydir.c, src/useradd.c: + selinux_file_context renamed set_selinux_file_context. + * lib/protoypes.h, libmisc/copydir.c, src/useradd.c: + Added reset_selinux_file_context. + * src/useradd.c: Check the return value of + set_selinux_file_context and reset_selinux_file_context. + * libmisc/copydir.c: Check the return value of + reset_selinux_file_context. + 2010-08-28 Nicolas François * src/su.c: Fix handling of environment variables when diff --git a/lib/prototypes.h b/lib/prototypes.h index 8f9db9c6..a8993268 100644 --- a/lib/prototypes.h +++ b/lib/prototypes.h @@ -123,7 +123,8 @@ extern int copy_tree (const char *src_root, const char *dst_root, uid_t old_uid, uid_t new_uid, gid_t old_gid, gid_t new_gid); #ifdef WITH_SELINUX -extern int selinux_file_context (const char *dst_name); +extern int set_selinux_file_context (const char *dst_name); +extern int reset_selinux_file_context (void); #endif /* encrypt.c */ diff --git a/libmisc/copydir.c b/libmisc/copydir.c index c4a561da..85155ae4 100644 --- a/libmisc/copydir.c +++ b/libmisc/copydir.c @@ -55,6 +55,11 @@ #include #endif /* WITH_ATTR */ +#ifdef WITH_SELINUX +static bool selinux_checked = false; +static bool selinux_enabled; +#endif /* WITH_SELINUX */ + static /*@null@*/const char *src_orig; static /*@null@*/const char *dst_orig; @@ -109,20 +114,17 @@ static int fchown_if_needed (int fdst, const struct stat *statp, #ifdef WITH_SELINUX /* - * selinux_file_context - Set the security context before any file or - * directory creation. + * set_selinux_file_context - Set the security context before any file or + * directory creation. * - * selinux_file_context () should be called before any creation of file, - * symlink, directory, ... + * set_selinux_file_context () should be called before any creation + * of file, symlink, directory, ... * * Callers may have to Reset SELinux to create files with default - * contexts: - * setfscreatecon (NULL); + * contexts with reset_selinux_file_context */ -int selinux_file_context (const char *dst_name) +int set_selinux_file_context (const char *dst_name) { - static bool selinux_checked = false; - static bool selinux_enabled; /*@null@*/security_context_t scontext = NULL; if (!selinux_checked) { @@ -147,6 +149,27 @@ int selinux_file_context (const char *dst_name) } return 0; } + +/* + * reset_selinux_file_context - Reset the security context to the default + * policy behavior + * + * reset_selinux_file_context () should be called after the context + * was changed with set_selinux_file_context () + */ +int reset_selinux_file_context (void) +{ + if (!selinux_checked) { + selinux_enabled = is_selinux_enabled () > 0; + selinux_checked = true; + } + if (selinux_enabled) { + if (setfscreatecon (NULL) != 0) { + return 1; + } + } + return 0; +} #endif /* WITH_SELINUX */ #if defined(WITH_ACL) || defined(WITH_ATTR) @@ -373,8 +396,14 @@ int copy_tree (const char *src_root, const char *dst_root, } #ifdef WITH_SELINUX - /* Reset SELinux to create files with default contexts */ - if (setfscreatecon (NULL) != 0) { + /* Reset SELinux to create files with default contexts. + * Note that the context is only reset on exit of copy_tree (it is + * assumed that the program would quit without needing a restored + * context if copy_tree failed previously), and that copy_tree can + * be called recursively (hence the context is set on the + * sub-functions of copy_entry). + */ + if (reset_selinux_file_context () != 0) { err = -1; } #endif /* WITH_SELINUX */ @@ -511,7 +540,7 @@ static int copy_dir (const char *src, const char *dst, */ #ifdef WITH_SELINUX - if (selinux_file_context (dst) != 0) { + if (set_selinux_file_context (dst) != 0) { return -1; } #endif /* WITH_SELINUX */ @@ -629,7 +658,7 @@ static int copy_symlink (const char *src, const char *dst, } #ifdef WITH_SELINUX - if (selinux_file_context (dst) != 0) { + if (set_selinux_file_context (dst) != 0) { free (oldlink); return -1; } @@ -708,7 +737,7 @@ static int copy_special (const char *src, const char *dst, int err = 0; #ifdef WITH_SELINUX - if (selinux_file_context (dst) != 0) { + if (set_selinux_file_context (dst) != 0) { return -1; } #endif /* WITH_SELINUX */ @@ -765,7 +794,7 @@ static int copy_file (const char *src, const char *dst, return -1; } #ifdef WITH_SELINUX - if (selinux_file_context (dst) != 0) { + if (set_selinux_file_context (dst) != 0) { return -1; } #endif /* WITH_SELINUX */ diff --git a/src/useradd.c b/src/useradd.c index e8348b9f..b7d51715 100644 --- a/src/useradd.c +++ b/src/useradd.c @@ -1764,7 +1764,9 @@ static void create_home (void) { if (access (user_home, F_OK) != 0) { #ifdef WITH_SELINUX - selinux_file_context (user_home); + if (set_selinux_file_context (user_home) != 0) { + fail_exit (E_HOMEDIR); + } #endif /* XXX - create missing parent directories. --marekm */ if (mkdir (user_home, 0) != 0) { @@ -1791,7 +1793,9 @@ static void create_home (void) #endif #ifdef WITH_SELINUX /* Reset SELinux to create files with default contexts */ - setfscreatecon (NULL); + if (reset_selinux_file_context () != 0) { + fail_exit (E_HOMEDIR); + } #endif } }