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