libreport  2.1.11.42.el7.47.gd10d.dirty
A tool to inform users about various problems on the running system
dump_dir.h
1 /*
2  On-disk storage of problem data
3 
4  Copyright (C) 2009 Zdenek Prikryl (zprikryl@redhat.com)
5  Copyright (C) 2009 RedHat inc.
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License along
18  with this program; if not, write to the Free Software Foundation, Inc.,
19  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21 #ifndef LIBREPORT_DUMP_DIR_H_
22 #define LIBREPORT_DUMP_DIR_H_
23 
24 /* For const_string_vector_const_ptr_t */
25 #include "libreport_types.h"
26 
27 #include <stdint.h>
28 #include <stdio.h>
29 
30 /* For DIR */
31 #include <sys/types.h>
32 #include <dirent.h>
33 
34 /* Fore GList */
35 #include <glib.h>
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 /* Utility function */
42 int create_symlink_lockfile(const char *filename, const char *pid_str);
43 int create_symlink_lockfile_at(int dir_fd, const char *filename,
44  const char *pid_str, bool log_all_warnings);
45 
46 /* Opens filename for reading relatively to a directory represented by dir_fd.
47  * The function fails if the file is symbolic link, directory or hard link.
48  */
49 int secure_openat_read(int dir_fd, const char *filename);
50 
51 enum {
52  DD_FAIL_QUIETLY_ENOENT = (1 << 0),
53  DD_FAIL_QUIETLY_EACCES = (1 << 1),
54  /* Open symlinks. dd_* funcs don't open symlinks by default */
55  DD_OPEN_FOLLOW = (1 << 2),
56  DD_OPEN_READONLY = (1 << 3),
57  DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE = (1 << 4),
58  DD_DONT_WAIT_FOR_LOCK = (1 << 5),
59  /* Create the new dump directory with parent directories (mkdir -p)*/
60  DD_CREATE_PARENTS = (1 << 6),
61 };
62 
63 struct dump_dir {
64  char *dd_dirname;
65  DIR *next_dir;
66  int locked;
67  uid_t dd_uid;
68  gid_t dd_gid;
69  /* mode of saved files */
70  mode_t mode;
71  time_t dd_time;
72  char *dd_type;
73  int dd_fd;
74 
75  /* In case of recursive locking the first caller owns the lock and is
76  * responsible for unlocking. The consecutive dd_lock() callers acquire the
77  * lock but are not able to unlock the dump directory.
78  */
79  int owns_lock;
80 };
81 
82 void dd_close(struct dump_dir *dd);
83 
84 /* Opens the given path and returns the resulting file descriptor.
85  */
86 int dd_openfd(const char *dir);
87 /* Opens the given path
88  */
89 struct dump_dir *dd_opendir(const char *dir, int flags);
90 
91 /* Re-opens a dump_dir opened with DD_OPEN_FD_ONLY.
92  *
93  * The passed dump_dir must not be used any more and the return value must be
94  * used instead.
95  *
96  * The passed flags must not contain DD_OPEN_FD_ONLY.
97  *
98  * The passed dump_dir must not be already locked.
99  */
100 
101 /* Skips dd_openfd(dir) and uses the given file descriptor instead
102  */
103 struct dump_dir *dd_fdopendir(int dir_fd, const char *dir, int flags);
104 
105 struct dump_dir *dd_create_skeleton(const char *dir, uid_t uid, mode_t mode, int flags);
106 int dd_reset_ownership(struct dump_dir *dd);
107 /* Pass uid = (uid_t)-1L to disable chown'ing of newly created files
108  * (IOW: if you aren't running under root):
109  */
110 struct dump_dir *dd_create(const char *dir, uid_t uid, mode_t mode);
111 
112 void dd_create_basic_files(struct dump_dir *dd, uid_t uid, const char *chroot_dir);
113 int dd_exist(const struct dump_dir *dd, const char *path);
114 void dd_sanitize_mode_and_owner(struct dump_dir *dd);
115 
116 DIR *dd_init_next_file(struct dump_dir *dd);
117 int dd_get_next_file(struct dump_dir *dd, char **short_name, char **full_name);
118 
119 char* dd_load_text_ext(const struct dump_dir *dd, const char *name, unsigned flags);
120 char* dd_load_text(const struct dump_dir *dd, const char *name);
121 
122 /* Returns value of environment variable with given name.
123  *
124  * @param dd Dump directory
125  * @param name Variables's name
126  * @param value Return value.
127  * @return 0 no success, or negative value if an error occurred (-ENOENT if the
128  * given dd does not support environment variables).
129  */
130 int dd_get_env_variable(struct dump_dir *dd, const char *name, char **value);
131 
132 void dd_save_text(struct dump_dir *dd, const char *name, const char *data);
133 void dd_save_binary(struct dump_dir *dd, const char *name, const char *data, unsigned size);
134 int dd_copy_file(struct dump_dir *dd, const char *name, const char *source_path);
135 /* Returns value less than 0 if any error occured; otherwise returns size of an
136  * item in Bytes. If an item does not exist returns 0 instead of an error
137  * value.
138  */
139 long dd_get_item_size(struct dump_dir *dd, const char *name);
140 /* Deletes an item from dump directory
141  * On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
142  * For more about errno see unlink documentation
143  */
144 int dd_delete_item(struct dump_dir *dd, const char *name);
145 
146 /* Returns a file descriptor for the given name. The function is limited to open
147  * an element read only, write only or create new.
148  *
149  * O_RDONLY - opens an existing item for reading
150  * O_RDWR - removes an item, creates its file and opens the file for reading and writing
151  *
152  * @param dd Dump directory
153  * @param name The name of the item
154  * @param flags One of these : O_RDONLY, O_RDWR
155  * @return Negative number on error
156  */
157 int dd_open_item(struct dump_dir *dd, const char *name, int flags);
158 
159 /* Returns a FILE for the given name. The function is limited to open
160  * an element read only, write only or create new.
161  *
162  * O_RDONLY - opens an existing file for reading
163  * O_RDWR - removes an item, creates its file and opens the file for reading and writing
164  *
165  * @param dd Dump directory
166  * @param name The name of the item
167  * @param flags One of these : O_RDONLY, O_RDWR
168  * @return NULL on error
169  */
170 FILE *dd_open_item_file(struct dump_dir *dd, const char *name, int flags);
171 
172 /* Returns 0 if directory is deleted or not found */
173 int dd_delete(struct dump_dir *dd);
174 int dd_rename(struct dump_dir *dd, const char *new_path);
175 /* Changes owner of dump dir
176  * Uses two different strategies selected at build time by
177  * DUMP_DIR_OWNED_BY_USER configuration:
178  * <= 0 : owner = abrt user's uid, group = new_uid's gid
179  * > 0 : owner = new_uid, group = abrt group's gid
180  *
181  * On success, zero is returned. On error, -1 is returned.
182  */
183 int dd_chown(struct dump_dir *dd, uid_t new_uid);
184 
185 
186 /* reported_to handling */
188  char *label;
189  char *url;
190  char *msg;
191  char *bthash;
192  time_t timestamp;
193  /* ^^^ if you add more fields, don't forget to update free_report_result() */
194 };
195 typedef struct report_result report_result_t;
196 
197 /* Appends a new unique line to the list of report results
198  *
199  * If the reported_to data already contains the given line, the line will not
200  * be added again.
201  *
202  * @param reported_to The data
203  * @param line The appended line
204  * @return 1 if the line was added at the end of the reported_to; otherwise 0.
205  */
206 #define add_reported_to_data libreport_add_reported_to_data
207 int add_reported_to_data(char **reported_to, const char *line);
208 
209 /* Appends a new unique entry to the list of report results
210  *
211  * result->label must be non-empty string which does not contain ':' character.
212  *
213  * The function converts the result to a valid reported_to line and calls
214  * add_reported_to_data().
215  *
216  * @param reported_to The data
217  * @param result The appended entry
218  * @return -EINVAL if result->label is invalid; otherwise return value of
219  * add_reported_to_data
220  */
221 #define add_reported_to_entry_data libreport_add_reported_to_entry_data
222 int add_reported_to_entry_data(char **reported_to, struct report_result *result);
223 
224 /* This is a wrapper of add_reported_to_data which accepts 'struct dump_dir *'
225  * in the first argument instead of 'char **'. The added line is stored in
226  * 'reported_to' dump directory file.
227  */
228 #define add_reported_to libreport_add_reported_to
229 void add_reported_to(struct dump_dir *dd, const char *line);
230 
231 /* This is a wrapper of add_reported_to_entry_data which accepts 'struct
232  * dump_dir *' in the first argument instead of 'char **'. The added entry is
233  * stored in 'reported_to' dump directory file.
234  */
235 #define add_reported_to_entry libreport_add_reported_to_entry
236 void add_reported_to_entry(struct dump_dir *dd, struct report_result *result);
237 
238 #define free_report_result libreport_free_report_result
239 void free_report_result(struct report_result *result);
240 #define find_in_reported_to_data libreport_find_in_reported_to_data
241 report_result_t *find_in_reported_to_data(const char *reported_to, const char *report_label);
242 #define find_in_reported_to libreport_find_in_reported_to
243 report_result_t *find_in_reported_to(struct dump_dir *dd, const char *report_label);
244 #define read_entire_reported_to_data libreport_read_entire_reported_to_data
245 GList *read_entire_reported_to_data(const char* reported_to);
246 #define read_entire_reported_to libreport_read_entire_reported_to
247 GList *read_entire_reported_to(struct dump_dir *dd);
248 
249 
250 void delete_dump_dir(const char *dirname);
251 /* Checks dump dir accessibility for particular uid.
252  *
253  * If the directory doesn't exist the directory is not accessible and errno is
254  * set to ENOTDIR.
255  *
256  * Returns non zero if dump dir is accessible otherwise return 0 value.
257  */
258 int dump_dir_accessible_by_uid(const char *dirname, uid_t uid);
259 int fdump_dir_accessible_by_uid(int dir_fd, uid_t uid);
260 
261 enum {
262  DD_STAT_ACCESSIBLE_BY_UID = 1,
263  DD_STAT_OWNED_BY_UID = DD_STAT_ACCESSIBLE_BY_UID << 1,
264 };
265 
266 /* Gets information about a dump directory for particular uid.
267  *
268  * If the directory doesn't exist the directory is not accessible and errno is
269  * set to ENOTDIR.
270  *
271  * Returns negative number if error occurred otherwise returns 0 or positive number.
272  */
273 int dump_dir_stat_for_uid(const char *dirname, uid_t uid);
274 int fdump_dir_stat_for_uid(int dir_fd, uid_t uid);
275 
276 /* creates not_reportable file in the problem directory and saves the
277  reason to it, which prevents libreport from reporting the problem
278  On success, zero is returned.
279  On error, -1 is returned and an error message is logged.
280  - this could probably happen only if the dump dir is not locked
281 */
282 int dd_mark_as_notreportable(struct dump_dir *dd, const char *reason);
283 
284 /* Creates a new archive from the dump directory contents
285  *
286  * The dd argument must be opened for reading.
287  *
288  * The archive_name must not exist. The file will be created with 0600 mode.
289  *
290  * The archive type is deduced from archive_name suffix. The supported archive
291  * suffixes are the following:
292  * - '.tag.gz' (note: the implementation uses child gzip process)
293  *
294  * The archive will include only the files that are not in the exclude_elements
295  * list. See get_global_always_excluded_elements().
296  *
297  * The argument "flags" is currently unused.
298  *
299  * @return 0 on success; otherwise non-0 value. -ENOSYS if archive type is not
300  * supported. -EEXIST if the archive file already exists. -ECHILD if child
301  * process fails. Other negative values can be converted to errno values by
302  * turning them positive.
303  */
304 int dd_create_archive(struct dump_dir *dd, const char *archive_name,
305  const_string_vector_const_ptr_t exclude_elements, int flags);
306 
307 #ifdef __cplusplus
308 }
309 #endif
310 
311 #endif