libreport  2.6.3
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 #include <stdint.h>
25 
26 /* For DIR */
27 #include <sys/types.h>
28 #include <dirent.h>
29 
30 /* Fore GList */
31 #include <glib.h>
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 /* Utility function */
38 int create_symlink_lockfile(const char *filename, const char *pid_str);
39 int create_symlink_lockfile_at(int dir_fd, const char *filename, const char *pid_str);
40 
41 /* Opens filename for reading relatively to a directory represented by dir_fd.
42  * The function fails if the file is symbolic link, directory or hard link.
43  */
44 int secure_openat_read(int dir_fd, const char *filename);
45 
46 /******************************************************************************/
47 /* Global variables */
48 /******************************************************************************/
49 
50 /* UID of super-user (default 0)
51  *
52  * This variable is used by the dd* functions when they access security
53  * sensitive elements. The functions will ONLY TRUST the contents of those
54  * elements that ARE OWNED by super-user.
55  */
56 extern uid_t dd_g_super_user_uid;
57 
58 /* GID of a dump diretory created via dd_create() with uid != -1
59  *
60  * The default value is -1 which means that the dd* functions must ignore this
61  * variable.
62  *
63  * Initialize this variable only if you don't want to use the default group
64  * ('abrt').
65  */
66 extern gid_t dd_g_fs_group_gid;
67 
68 /******************************************************************************/
69 /* Dump Directory */
70 /******************************************************************************/
71 
72 enum {
73  DD_FAIL_QUIETLY_ENOENT = (1 << 0),
74  DD_FAIL_QUIETLY_EACCES = (1 << 1),
75  /* Open symlinks. dd_* funcs don't open symlinks by default */
76  DD_OPEN_FOLLOW = (1 << 2),
77  DD_OPEN_READONLY = (1 << 3),
78  DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE = (1 << 4),
79  DD_DONT_WAIT_FOR_LOCK = (1 << 5),
80  /* Create the new dump directory with parent directories (mkdir -p)*/
81  DD_CREATE_PARENTS = (1 << 6),
82  /* Initializes internal data, opens file descriptors and returns the
83  * structure. This flag is useful for testing whether a directory
84  * exists and to perform stat operations.
85  */
86  DD_OPEN_FD_ONLY = (1 << 7),
87 };
88 
89 struct dump_dir {
90  char *dd_dirname;
91  DIR *next_dir;
92  int locked;
93  uid_t dd_uid;
94  gid_t dd_gid;
95  /* mode of saved files */
96  mode_t mode;
97  time_t dd_time;
98  char *dd_type;
99 
100  /* In case of recursive locking the first caller owns the lock and is
101  * responsible for unlocking. The consecutive dd_lock() callers acquire the
102  * lock but are not able to unlock the dump directory.
103  */
104  int owns_lock;
105  int dd_fd;
106  /* Never use this member directly, it is intialized on demand in
107  * dd_get_meta_data_dir_fd()
108  */
109  int dd_md_fd;
110 };
111 
112 void dd_close(struct dump_dir *dd);
113 
114 /* Opens the given path
115  */
116 struct dump_dir *dd_opendir(const char *dir, int flags);
117 
118 /* Re-opens a dump_dir opened with DD_OPEN_FD_ONLY.
119  *
120  * The passed dump_dir must not be used any more and the return value must be
121  * used instead.
122  *
123  * The passed flags must not contain DD_OPEN_FD_ONLY.
124  *
125  * The passed dump_dir must not be already locked.
126  */
127 struct dump_dir *dd_fdopendir(struct dump_dir *dd, int flags);
128 
129 struct dump_dir *dd_create_skeleton(const char *dir, uid_t uid, mode_t mode, int flags);
130 int dd_reset_ownership(struct dump_dir *dd);
131 /* Pass uid = (uid_t)-1L to disable chown'ing of newly created files
132  * (IOW: if you aren't running under root):
133  */
134 struct dump_dir *dd_create(const char *dir, uid_t uid, mode_t mode);
135 
136 /* Creates the basic files except 'type' and sets the dump dir owner to passed
137  * 'uid'.
138  *
139  * The file 'type' is required and must be added with dd_save_text().
140  *
141  * If you want to have owner different than the problem 'uid', than pass -1 and
142  * add the file 'uid' with dd_save_text()
143  *
144  * List of created files:
145  * - time
146  * - last_occurrence
147  * - uid
148  * - kernel
149  * - architecture
150  * - hostname
151  * - os_info
152  * - os_release
153  *
154  * If any of these files has a counterpart in a chroot directory (os_info,
155  * os_relase), creates an element with the prefix "root_"
156  */
157 void dd_create_basic_files(struct dump_dir *dd, uid_t uid, const char *chroot_dir);
158 int dd_exist(const struct dump_dir *dd, const char *path);
159 void dd_sanitize_mode_and_owner(struct dump_dir *dd);
160 
161 DIR *dd_init_next_file(struct dump_dir *dd);
162 int dd_get_next_file(struct dump_dir *dd, char **short_name, char **full_name);
163 
164 char *load_text_file(const char *path, unsigned flags);
165 
166 char* dd_load_text_ext(const struct dump_dir *dd, const char *name, unsigned flags);
167 char* dd_load_text(const struct dump_dir *dd, const char *name);
168 int dd_load_int32(const struct dump_dir *dd, const char *name, int32_t *value);
169 int dd_load_uint32(const struct dump_dir *dd, const char *name, uint32_t *value);
170 int dd_load_int64(const struct dump_dir *dd, const char *name, int64_t *value);
171 int dd_load_uint64(const struct dump_dir *dd, const char *name, uint64_t *value);
172 void dd_save_text(struct dump_dir *dd, const char *name, const char *data);
173 void dd_save_binary(struct dump_dir *dd, const char *name, const char *data, unsigned size);
174 int dd_copy_file(struct dump_dir *dd, const char *name, const char *source_path);
175 int dd_copy_file_unpack(struct dump_dir *dd, const char *name, const char *source_path);
176 /* Returns value less than 0 if any error occured; otherwise returns size of an
177  * item in Bytes. If an item does not exist returns 0 instead of an error
178  * value.
179  */
180 long dd_get_item_size(struct dump_dir *dd, const char *name);
181 /* Deletes an item from dump directory
182  * On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
183  * For more about errno see unlink documentation
184  */
185 int dd_delete_item(struct dump_dir *dd, const char *name);
186 /* Returns 0 if directory is deleted or not found */
187 int dd_delete(struct dump_dir *dd);
188 int dd_rename(struct dump_dir *dd, const char *new_path);
189 /* Changes owner of dump dir
190  * Uses two different strategies selected at build time by
191  * DUMP_DIR_OWNED_BY_USER configuration:
192  * <= 0 : owner = abrt user's uid, group = new_uid's gid
193  * > 0 : owner = new_uid, group = abrt group's gid
194  *
195  * On success, zero is returned. On error, -1 is returned.
196  */
197 int dd_chown(struct dump_dir *dd, uid_t new_uid);
198 
199 /* Sets a new owner (does NOT chown the directory)
200  *
201  * Does not validate the passed uid.
202  * The given dump_dir must be opened for writing.
203  */
204 int dd_set_owner(struct dump_dir *dd, uid_t owner);
205 
206 /* Makes the dump directory owned by nobody.
207  *
208  * The directory will be accessible for all users.
209  * The given dump_dir must be opened for writing.
210  */
211 int dd_set_no_owner(struct dump_dir *dd);
212 
213 /* Gets the owner
214  *
215  * If meta-data misses owner, returns fs owner.
216  * Can be used with DD_OPEN_FD_ONLY.
217  */
218 uid_t dd_get_owner(struct dump_dir *dd);
219 
220 /* reported_to handling */
221 #define add_reported_to_data libreport_add_reported_to_data
222 int add_reported_to_data(char **reported_to, const char *line);
223 #define add_reported_to libreport_add_reported_to
224 void add_reported_to(struct dump_dir *dd, const char *line);
226  char *label;
227  char *url;
228  char *msg;
229  char *bthash;
230  /* char *whole_line; */
231  /* time_t timestamp; */
232  /* ^^^ if you add more fields, don't forget to update free_report_result() */
233 };
234 typedef struct report_result report_result_t;
235 #define free_report_result libreport_free_report_result
236 void free_report_result(struct report_result *result);
237 #define find_in_reported_to_data libreport_find_in_reported_to_data
238 report_result_t *find_in_reported_to_data(const char *reported_to, const char *report_label);
239 #define find_in_reported_to libreport_find_in_reported_to
240 report_result_t *find_in_reported_to(struct dump_dir *dd, const char *report_label);
241 #define read_entire_reported_to_data libreport_read_entire_reported_to_data
242 GList *read_entire_reported_to_data(const char* reported_to);
243 #define read_entire_reported_to libreport_read_entire_reported_to
244 GList *read_entire_reported_to(struct dump_dir *dd);
245 
246 
247 void delete_dump_dir(const char *dirname);
248 /* Checks dump dir accessibility for particular uid.
249  *
250  * If the directory doesn't exist the directory is not accessible and errno is
251  * set to ENOTDIR.
252  *
253  * Returns non zero if dump dir is accessible otherwise return 0 value.
254  */
255 int dump_dir_accessible_by_uid(const char *dirname, uid_t uid);
256 /* Returns the same information as dump_dir_accessible_by_uid
257  *
258  * The passed dump_dir can be opened with DD_OPEN_FD_ONLY
259  */
260 int dd_accessible_by_uid(struct dump_dir *dd, uid_t uid);
261 
262 enum {
263  DD_STAT_ACCESSIBLE_BY_UID = 1,
264  DD_STAT_OWNED_BY_UID = DD_STAT_ACCESSIBLE_BY_UID << 1,
265  DD_STAT_NO_OWNER = DD_STAT_OWNED_BY_UID << 1,
266 };
267 
268 /* Gets information about a dump directory for particular uid.
269  *
270  * If the directory doesn't exist the directory is not accessible and errno is
271  * set to ENOTDIR.
272  *
273  * Returns negative number if error occurred otherwise returns 0 or positive number.
274  */
275 int dump_dir_stat_for_uid(const char *dirname, uid_t uid);
276 /* Returns the same information as dump_dir_stat_for_uid
277  *
278  * The passed dump_dir can be opened with DD_OPEN_FD_ONLY
279  */
280 int dd_stat_for_uid(struct dump_dir *dd, uid_t uid);
281 
282 /* creates not_reportable file in the problem directory and saves the
283  reason to it, which prevents libreport from reporting the problem
284  On success, zero is returned.
285  On error, -1 is returned and an error message is logged.
286  - this could probably happen only if the dump dir is not locked
287 */
288 int dd_mark_as_notreportable(struct dump_dir *dd, const char *reason);
289 
290 typedef int (*save_data_call_back)(struct dump_dir *, void *args);
291 
292 /* Saves data in a new dump directory
293  *
294  * Creates a new dump directory in "problem dump location", adds the basic
295  * information to the new directory, calls given callback to allow callees to
296  * customize the dump dir contents (save problem data) and commits the dump
297  * directory (makes the directory visible for a problem daemon).
298  */
299 struct dump_dir *create_dump_dir(const char *base_dir_name, const char *type,
300  uid_t uid, save_data_call_back save_data, void *args);
301 #ifdef __cplusplus
302 }
303 #endif
304 
305 #endif