libexplain
1.4.D001
|
00001 /* 00002 * libexplain - Explain errno values returned by libc functions 00003 * Copyright (C) 2008-2011, 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/string.h> 00021 #include <libexplain/ac/sys/param.h> /* for PATH_MAX except Solaris */ 00022 #include <libexplain/ac/sys/stat.h> 00023 00024 #include <libexplain/buffer/caption_name_type.h> 00025 #include <libexplain/buffer/dac.h> 00026 #include <libexplain/buffer/does_not_have_inode_modify_permission.h> 00027 #include <libexplain/buffer/errno/path_resolution.h> 00028 #include <libexplain/buffer/file_type.h> 00029 #include <libexplain/buffer/gettext.h> 00030 #include <libexplain/buffer/uid.h> 00031 #include <libexplain/dirname.h> 00032 #include <libexplain/name_max.h> 00033 00034 00035 void 00036 explain_buffer_does_not_have_inode_modify_permission1( 00037 explain_string_buffer_t *sb, const char *pathname, 00038 const struct stat *pathname_st, const char *caption, 00039 const explain_have_identity_t *hip) 00040 { 00041 struct stat dirname_st; 00042 char filename[NAME_MAX + 1]; 00043 char dirname[PATH_MAX + 1]; 00044 00045 explain_dirname(dirname, pathname, sizeof(dirname)); 00046 if (stat(dirname, &dirname_st) < 0) 00047 { 00048 memset(&dirname_st, 0, sizeof(dirname_st)); 00049 dirname_st.st_mode = S_IFDIR; 00050 } 00051 explain_basename(filename, pathname, sizeof(filename)); 00052 00053 explain_buffer_does_not_have_inode_modify_permission 00054 ( 00055 sb, 00056 filename, 00057 pathname_st, 00058 caption, 00059 dirname, 00060 &dirname_st, 00061 hip 00062 ); 00063 } 00064 00065 00066 static void 00067 process_does_not_match_the_owner_uid(explain_string_buffer_t *sb, 00068 const char *kind_of_uid, const char *puid, const char *caption, 00069 int st_uid) 00070 { 00071 char fuid[40]; 00072 explain_string_buffer_t fuid_sb; 00073 00074 explain_string_buffer_init(&fuid_sb, fuid, sizeof(fuid)); 00075 explain_buffer_uid(&fuid_sb, st_uid); 00076 00077 explain_string_buffer_printf_gettext 00078 ( 00079 sb, 00080 /* 00081 * xgettext: This message supplements the "no inode modify 00082 * permission" message, explaining that the process effective UID 00083 * must match the file owner UID. 00084 * 00085 * %1$s => the kind of UID, either "real UID" or "effective UID", 00086 * already translated 00087 * %2$s => the numeric UID of the process, and the corresponding 00088 * login name from the password file, if available. 00089 * %3$s => the name of the offending system call argument, 00090 * possibly with some additional file type info 00091 * %4$s => the numeric UID of the file owner, and the 00092 * corresponding login name from the password file, if 00093 * available. 00094 */ 00095 i18n("the process %s %s does not match the %s owner UID %s"), 00096 kind_of_uid, 00097 puid, 00098 caption, 00099 fuid 00100 ); 00101 explain_buffer_dac_fowner(sb); 00102 } 00103 00104 00105 void 00106 explain_buffer_does_not_have_inode_modify_permission_fd( 00107 explain_string_buffer_t *sb, int fildes, const char *fildes_caption) 00108 { 00109 struct stat st; 00110 struct stat *st_p; 00111 explain_have_identity_t id; 00112 00113 explain_have_identity_init(&id); 00114 st_p = &st; 00115 if (fstat(fildes, st_p) < 0) 00116 st_p = 0; 00117 explain_buffer_does_not_have_inode_modify_permission_fd_st 00118 ( 00119 sb, 00120 st_p, 00121 fildes_caption, 00122 &id 00123 ); 00124 } 00125 00126 00127 void 00128 explain_buffer_does_not_have_inode_modify_permission_fd_st( 00129 explain_string_buffer_t *sb, const struct stat *fildes_st, 00130 const char *fildes_caption, const explain_have_identity_t *hip) 00131 { 00132 explain_string_buffer_t puid_sb; 00133 explain_string_buffer_t caption_sb; 00134 const char *kind_of_uid; 00135 char puid[40]; 00136 char caption[100]; 00137 00138 explain_buffer_gettext 00139 ( 00140 sb, 00141 /* 00142 * xgettext: This message is used when a process does not have 00143 * inode modification permission to something it attempts to 00144 * modify); for example, fchmod. 00145 */ 00146 i18n("the process does not have inode modification permission") 00147 ); 00148 if (!fildes_st) 00149 { 00150 explain_buffer_dac_fowner(sb); 00151 return; 00152 } 00153 00154 kind_of_uid = explain_have_identity_kind_of_uid(hip); 00155 00156 /* 00157 * Give more information: tell them who they are (this can be a 00158 * surprise to users of set-UID programs) and who owns the file. 00159 */ 00160 explain_string_buffer_init(&puid_sb, puid, sizeof(puid)); 00161 explain_buffer_uid(&puid_sb, hip->uid); 00162 00163 explain_string_buffer_init(&caption_sb, caption, sizeof(caption)); 00164 explain_buffer_caption_name_type_st 00165 ( 00166 &caption_sb, 00167 fildes_caption, 00168 0, 00169 fildes_st 00170 ); 00171 00172 explain_string_buffer_puts(sb, ", "); 00173 process_does_not_match_the_owner_uid 00174 ( 00175 sb, 00176 kind_of_uid, 00177 puid, 00178 caption, 00179 fildes_st->st_uid 00180 ); 00181 } 00182 00183 00184 void 00185 explain_buffer_does_not_have_inode_modify_permission( 00186 explain_string_buffer_t *sb, const char *comp, 00187 const struct stat *comp_st, const char *caption, const char *dir, 00188 const struct stat *dir_st, const explain_have_identity_t *hip) 00189 { 00190 char final_part[NAME_MAX * 4 + 100]; 00191 explain_string_buffer_t final_part_sb; 00192 char dir_part[PATH_MAX * 4 + 100]; 00193 explain_string_buffer_t dir_part_sb; 00194 const char *kind_of_uid; 00195 char puid[40]; 00196 explain_string_buffer_t puid_sb; 00197 00198 explain_string_buffer_init 00199 ( 00200 &final_part_sb, 00201 final_part, 00202 sizeof(final_part) 00203 ); 00204 explain_buffer_caption_name_type_st 00205 ( 00206 &final_part_sb, 00207 0, 00208 comp, 00209 comp_st 00210 ); 00211 explain_string_buffer_init(&dir_part_sb, dir_part, sizeof(dir_part)); 00212 explain_buffer_caption_name_type_st 00213 ( 00214 &dir_part_sb, 00215 caption, 00216 dir, 00217 dir_st 00218 ); 00219 00220 explain_string_buffer_printf_gettext 00221 ( 00222 sb, 00223 /* 00224 * xgettext: This message is used when a process does not have 00225 * inode modification permission to something it attempts to 00226 * modify); for example, chmod. 00227 * Different language grammars may need to rearrange the parts. 00228 * 00229 * %1$s => the name of the final component of the path, the 00230 * regular file in question (will never have slashes). 00231 * It will in clude the name of the file, and the file 00232 * type "regular file". 00233 * %2$s => the name of the directory that contains the regular 00234 * file to be executed; it may have zero, one or more 00235 * slashes in it. Will include the name of the function 00236 * call argument, the name of the directory, and the 00237 * file type "directory". 00238 */ 00239 i18n("the process does not have inode modification permission " 00240 "to the %s in the %s"), 00241 final_part, 00242 dir_part 00243 ); 00244 00245 kind_of_uid = explain_have_identity_kind_of_uid(hip); 00246 00247 /* 00248 * Give more information: tell them who they are (this can be a 00249 * surprise to users of set-UID programs) and who owns the file. 00250 */ 00251 explain_string_buffer_init(&puid_sb, puid, sizeof(puid)); 00252 explain_buffer_uid(&puid_sb, hip->uid); 00253 00254 explain_string_buffer_init 00255 ( 00256 &final_part_sb, 00257 final_part, 00258 sizeof(final_part) 00259 ); 00260 explain_buffer_file_type_st(&final_part_sb, comp_st); 00261 00262 explain_string_buffer_puts(sb, ", "); 00263 process_does_not_match_the_owner_uid 00264 ( 00265 sb, 00266 kind_of_uid, 00267 puid, 00268 final_part, 00269 comp_st->st_uid 00270 ); 00271 } 00272 00273 00274 /* vim: set ts=8 sw=4 et : */