libexplain
1.4.D001
|
00001 /* 00002 * libexplain - Explain errno values returned by libc functions 00003 * Copyright (C) 2010, 2013 Peter Miller 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU Lesser General Public License as 00007 * published by the Free Software Foundation; either version 3 of the 00008 * License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public License 00016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 */ 00018 00019 #include <libexplain/ac/limits.h> /* for PATH_MAX on Solaris */ 00020 #include <libexplain/ac/sys/param.h> /* for PATH_MAX except Solaris */ 00021 #include <libexplain/ac/sys/stat.h> 00022 #include <libexplain/ac/unistd.h> 00023 00024 #include <libexplain/buffer/dac.h> 00025 #include <libexplain/buffer/eperm.h> 00026 #include <libexplain/buffer/uid.h> 00027 #include <libexplain/dirname.h> 00028 00029 00030 void 00031 explain_buffer_eperm_unlink(explain_string_buffer_t *sb, const char *pathname, 00032 const char *pathname_caption, const char *syscall_name) 00033 { 00034 struct stat pathname_st; 00035 struct stat dir_st; 00036 char dir[PATH_MAX]; 00037 00038 explain_dirname(dir, pathname, sizeof(dir)); 00039 if 00040 ( 00041 stat(dir, &dir_st) >= 0 00042 && 00043 (dir_st.st_mode & S_ISVTX) 00044 && 00045 geteuid() != dir_st.st_uid 00046 && 00047 stat(pathname, &pathname_st) >= 0 00048 && 00049 geteuid() != pathname_st.st_uid 00050 ) 00051 { 00052 explain_string_buffer_t proc_uid_sb; 00053 explain_string_buffer_t pathname_uid_sb; 00054 explain_string_buffer_t dir_uid_sb; 00055 explain_string_buffer_t dir_quoted_sb; 00056 char proc_uid[50]; 00057 char pathname_uid[50]; 00058 char dir_uid[50]; 00059 char dir_quoted[PATH_MAX]; 00060 00061 explain_string_buffer_init(&dir_quoted_sb, dir_quoted, 00062 sizeof(dir_quoted)); 00063 explain_string_buffer_puts_quoted(&dir_quoted_sb, dir); 00064 00065 explain_string_buffer_init(&proc_uid_sb, proc_uid, 00066 sizeof(proc_uid)); 00067 explain_buffer_uid(&proc_uid_sb, geteuid()); 00068 00069 explain_string_buffer_init(&pathname_uid_sb, pathname_uid, 00070 sizeof(pathname_uid)); 00071 explain_buffer_uid(&pathname_uid_sb, pathname_st.st_uid); 00072 00073 explain_string_buffer_init(&dir_uid_sb, dir_uid, 00074 sizeof(dir_uid)); 00075 explain_buffer_uid(&dir_uid_sb, dir_st.st_uid); 00076 00077 explain_string_buffer_printf_gettext 00078 ( 00079 sb, 00080 /* 00081 * xgettext: This error message is used to explain an EPERM error 00082 * reported by the unlink(2) system call, in the case where the 00083 * directory containing pathname has the sticky bit (S_ISVTX) set 00084 * and the process's effective UID is neither the UID of the file to 00085 * be deleted nor that of the directory containing it. 00086 * 00087 * %1$s => The path for the directory containing the file ot be 00088 * unlinked, already quoted. 00089 * %2$s => The process's effective UID, and user name (already 00090 * quoted) if available 00091 * %3$s => The file to be deleted's effective UID, and user name 00092 * (already quoted) if available 00093 * %4$s => The directory's effective UID, and user name (already 00094 * quoted) if available 00095 */ 00096 i18n("the directory containing pathname (%s) has the " 00097 "sticky bit (S_ISVTX) set and the process's effective " 00098 "UID (%s) is neither the UID of the file to be deleted " 00099 "(%s) nor that of the directory containing it (%s)"), 00100 dir_quoted, 00101 proc_uid, 00102 pathname_uid, 00103 dir_uid 00104 ); 00105 } 00106 else 00107 { 00108 explain_string_buffer_printf_gettext 00109 ( 00110 sb, 00111 /* 00112 * xgettext: This error message is used to explain an EPERM 00113 * error reported by the unlink(2) system call, in the case 00114 * where the file system does not allow unlinking of files; 00115 * or, the directory containing pathname has the sticky 00116 * bit (S_ISVTX) set and the process's effective UID is 00117 * neither the UID of the file to be deleted nor that of the 00118 * directory containing it. 00119 * 00120 * $1$s => the name of the offending system call argument 00121 * $2$s => the name of the offended system call 00122 */ 00123 i18n("the %s does not refer to a file system object to which %s " 00124 "may be applied; or, the directory containing pathname has " 00125 "the sticky bit (S_ISVTX) set and the process's effective UID " 00126 "is neither the UID of the file to be deleted nor that of the " 00127 "directory containing it"), 00128 pathname_caption, 00129 syscall_name 00130 ); 00131 } 00132 explain_buffer_dac_fowner(sb); 00133 } 00134 00135 00136 /* vim: set ts=8 sw=4 et : */