]>
Commit | Line | Data |
---|---|---|
bd523de6 MT |
1 | diff -urNp tar-1.24-orig/configure.ac tar-1.24/configure.ac |
2 | --- tar-1.24-orig/configure.ac 2010-10-24 23:35:35.000000000 +0200 | |
3 | +++ tar-1.24/configure.ac 2010-10-25 10:24:52.548214037 +0200 | |
9f0833cd | 4 | @@ -44,7 +44,7 @@ AC_CHECK_HEADERS_ONCE(fcntl.h linux/fd.h |
bd523de6 | 5 | sys/param.h sys/device.h sys/gentape.h \ |
547b54ef MT |
6 | sys/inet.h sys/io/trioctl.h \ |
7 | sys/mtio.h sys/time.h sys/tprintf.h sys/tape.h \ | |
8 | - unistd.h locale.h) | |
9f0833cd | 9 | + unistd.h locale.h attr/xattr.h sys/acl.h) |
547b54ef MT |
10 | |
11 | AC_CHECK_HEADERS([sys/buf.h], [], [], | |
12 | [#if HAVE_SYS_PARAM_H | |
9f0833cd | 13 | @@ -91,6 +91,12 @@ gl_INIT |
547b54ef MT |
14 | tar_PAXUTILS |
15 | ||
bd523de6 | 16 | AC_CHECK_FUNCS_ONCE([fchmod fchown fsync lstat mkfifo readlink symlink]) |
547b54ef MT |
17 | +AC_CHECK_FUNCS(getxattr fgetxattr lgetxattr \ |
18 | + setxattr fsetxattr lsetxattr \ | |
19 | + listxattr flistxattr llistxattr, | |
20 | + AC_DEFINE(HAVE_XATTRS,,[Define if we have a working extended attributes]),) | |
547b54ef MT |
21 | +AC_CHECK_LIB(acl, acl_get_fd) |
22 | + | |
23 | AC_CHECK_DECLS([getgrgid],,, [#include <grp.h>]) | |
24 | AC_CHECK_DECLS([getpwuid],,, [#include <pwd.h>]) | |
25 | AC_CHECK_DECLS([time],,, [#include <time.h>]) | |
9f0833cd | 26 | @@ -214,6 +220,7 @@ AC_DEFINE_UNQUOTED(DEFAULT_QUOTING_STYLE |
547b54ef MT |
27 | # Iconv |
28 | AM_ICONV | |
29 | AC_CHECK_HEADERS(iconv.h) | |
547b54ef MT |
30 | +AC_CHECK_HEADERS(attr/xattr.h) |
31 | AC_CHECK_TYPE(iconv_t,:, | |
32 | AC_DEFINE(iconv_t, int, | |
33 | [Conversion descriptor type]), | |
9f0833cd MT |
34 | @@ -223,6 +230,17 @@ AC_CHECK_TYPE(iconv_t,:, |
35 | #endif | |
36 | ]) | |
37 | ||
38 | +AC_ARG_ENABLE(selinux, | |
39 | + AC_HELP_STRING([--enable-selinux], | |
40 | + [enable SELinux support (disabled by default)]), | |
41 | + [selinux_enabled=$enableval], | |
42 | + [selinux_enabled=no]) | |
43 | + | |
44 | +if test "x$selinux_enabled" = xyes; then | |
45 | + AC_CHECK_LIB(selinux, getfilecon) | |
46 | + AC_CHECK_HEADERS(selinux/selinux.h) | |
47 | +fi | |
48 | + | |
49 | # Gettext. | |
50 | AM_GNU_GETTEXT([external], [need-formatstring-macros]) | |
51 | AM_GNU_GETTEXT_VERSION([0.16]) | |
bd523de6 MT |
52 | diff -urNp tar-1.24-orig/doc/tar.texi tar-1.24/doc/tar.texi |
53 | --- tar-1.24-orig/doc/tar.texi 2010-10-24 20:07:54.000000000 +0200 | |
54 | +++ tar-1.24/doc/tar.texi 2010-10-25 10:24:52.554213688 +0200 | |
55 | @@ -2370,6 +2370,10 @@ Normally when creating an archive, @comm | |
547b54ef MT |
56 | @samp{/} from member names. This option disables that behavior. |
57 | @xref{absolute}. | |
58 | ||
59 | +@opsummary{acl} | |
60 | +@item --acls | |
61 | +Causes @command{tar} to store ACL's. @xref{Attributes}. | |
62 | + | |
63 | @opsummary{after-date} | |
64 | @item --after-date | |
65 | ||
bd523de6 | 66 | @@ -2915,6 +2919,10 @@ contents have changed (as opposed to jus |
547b54ef MT |
67 | also back up files for which any status information has |
68 | changed). @xref{after}. | |
69 | ||
70 | +@opsummary{no-acl} | |
71 | +@item --no-acls | |
72 | +Causes @command{tar} not to store and not to extract ACL's. @xref{Attributes}. | |
73 | + | |
74 | @opsummary{no-anchored} | |
75 | @item --no-anchored | |
76 | An exclude pattern can match any subsequence of the name's components. | |
bd523de6 | 77 | @@ -2998,11 +3006,21 @@ locations. Usually @command{tar} determ |
9f0833cd MT |
78 | the archive can be seeked or not. Use this option to disable this |
79 | mechanism. | |
547b54ef MT |
80 | |
81 | +@opsummary{no-selinux} | |
82 | +@item --no-selinux | |
83 | +Causes @command{tar} not to store and not to extract SELinux security context. | |
84 | +@xref{Attributes}. | |
85 | + | |
86 | @opsummary{no-unquote} | |
87 | @item --no-unquote | |
88 | Treat all input file or member names literally, do not interpret | |
89 | escape sequences. @xref{input name quoting}. | |
90 | ||
91 | +@opsummary{no-xattrs} | |
92 | +@item --no-xattrs | |
93 | +Causes @command{tar} not to store and not to extract xattrs. This option also | |
94 | +enables @option{--no-selinux} and @option{--no-acls}. @xref{Attributes}. | |
95 | + | |
96 | @opsummary{no-wildcards} | |
97 | @item --no-wildcards | |
98 | Do not use wildcards. | |
bd523de6 | 99 | @@ -3235,6 +3253,11 @@ in cases when such recognition fails. I |
9f0833cd MT |
100 | archive is open for reading (e.g. with @option{--list} or |
101 | @option{--extract} options). | |
547b54ef MT |
102 | |
103 | +@opsummary{selinux} | |
104 | +@item --selinux | |
105 | +Causes @command{tar} to store SElinux security context. @xref{Attributes}. | |
106 | + | |
107 | + | |
108 | @opsummary{show-defaults} | |
109 | @item --show-defaults | |
110 | ||
bd523de6 | 111 | @@ -3448,6 +3471,11 @@ Enable or disable warning messages ident |
9f0833cd MT |
112 | messages are suppressed if @var{keyword} is prefixed with @samp{no-}. |
113 | @xref{warnings}. | |
547b54ef MT |
114 | |
115 | +@opsummary{xattrs} | |
116 | +@item --xattrs | |
117 | +Causes @command{tar} to store xattrs. This option also enables | |
118 | +@option{--selinux} and @option{--acls}. @xref{Attributes}. | |
119 | + | |
120 | @opsummary{wildcards} | |
121 | @item --wildcards | |
122 | Use wildcards when matching member names with patterns. | |
bd523de6 | 123 | @@ -8643,6 +8671,8 @@ implementation able to read @samp{ustar} |
547b54ef MT |
124 | most @samp{posix} archives as well, with the only exception that any |
125 | additional information (such as long file names etc.) will in such | |
126 | case be extracted as plain text files along with the files it refers to. | |
127 | +This is the only format that can store ACLs, SELinux context and extended | |
128 | +attributes. | |
129 | ||
130 | This archive format will be the default format for future versions | |
131 | of @GNUTAR{}. | |
bd523de6 | 132 | @@ -9259,6 +9289,51 @@ Same as both @option{--same-permissions} |
547b54ef MT |
133 | |
134 | This option is deprecated, and will be removed in @GNUTAR{} version 1.23. | |
135 | ||
136 | +@opindex acls | |
137 | +@item --acls | |
138 | +This option causes @command{tar} to store the current ACL in the archive. | |
139 | + | |
140 | +The @option{--acls} option has no equivalent short option name. | |
141 | + | |
142 | +@opindex selinux | |
143 | +@item --selinux | |
144 | +This option causes @command{tar} to store the current SELinux security context | |
145 | +information in the archive. | |
146 | + | |
147 | +The @option{--selinux} option has no equivalent short option name. | |
148 | + | |
149 | +@opindex xattrs | |
150 | +@item --xattrs | |
151 | +This option causes @command{tar} to store the current extended attributes in | |
152 | +the archive. This option also enables @option{--acls} and @option{--selinux} if | |
153 | +they haven't been set already. | |
154 | + | |
155 | +The @option{--xattrs} option has no equivalent short option name. | |
156 | + | |
157 | +@opindex no-acls | |
158 | +@item --no-acls | |
159 | +This option causes @command{tar} not to store the current ACL in the archive | |
160 | +and not to extract any ACL information in an archive. | |
161 | + | |
162 | +The @option{--no-acls} option has no equivalent short option name. | |
163 | + | |
164 | +@opindex no-selinux | |
165 | +@item --no-selinux | |
166 | +This option causes @command{tar} not to store the current SELinux security | |
167 | +context information in the archive and not to extract any SELinux information in | |
168 | +an archive. | |
169 | + | |
170 | +The @option{--no-selinux} option has no equivalent short option name. | |
171 | + | |
172 | +@opindex no-xattrs | |
173 | +@item --no-xattrs | |
174 | +This option causes @command{tar} not to store the current extended attributes in | |
175 | +the archive and not to extract any extended attributes in an archive. This | |
176 | +option also enables @option{--no-acls} and @option{--no-selinux} if | |
177 | +they haven't been set already. | |
178 | + | |
179 | +The @option{--no-xattrs} option has no equivalent short option name. | |
180 | + | |
181 | @end table | |
182 | ||
183 | @node Portability | |
bd523de6 MT |
184 | diff -urNp tar-1.24-orig/src/common.h tar-1.24/src/common.h |
185 | --- tar-1.24-orig/src/common.h 2010-10-24 20:07:54.000000000 +0200 | |
186 | +++ tar-1.24/src/common.h 2010-10-25 10:24:52.558475456 +0200 | |
187 | @@ -253,6 +253,15 @@ GLOBAL int same_owner_option; | |
547b54ef MT |
188 | /* If positive, preserve permissions when extracting. */ |
189 | GLOBAL int same_permissions_option; | |
190 | ||
191 | +/* If positive, save the SELinux context. */ | |
192 | +GLOBAL int selinux_context_option; | |
193 | + | |
194 | +/* If positive, save the ACLs. */ | |
195 | +GLOBAL int acls_option; | |
196 | + | |
197 | +/* If positive, save the user and root xattrs. */ | |
198 | +GLOBAL int xattrs_option; | |
199 | + | |
200 | /* When set, strip the given number of file name components from the file name | |
201 | before extracting */ | |
202 | GLOBAL size_t strip_name_components; | |
bd523de6 | 203 | @@ -706,6 +715,9 @@ extern char *output_start; |
547b54ef MT |
204 | |
205 | void update_archive (void); | |
206 | ||
207 | +/* Module attrs.c. */ | |
208 | +#include "xattrs.h" | |
209 | + | |
210 | /* Module xheader.c. */ | |
211 | ||
bd523de6 MT |
212 | void xheader_decode (struct tar_stat_info *stat); |
213 | @@ -726,6 +738,12 @@ bool xheader_string_end (struct xheader | |
547b54ef MT |
214 | bool xheader_keyword_deleted_p (const char *kw); |
215 | char *xheader_format_name (struct tar_stat_info *st, const char *fmt, | |
216 | size_t n); | |
217 | +void xheader_xattr_init(struct tar_stat_info *st); | |
218 | +void xheader_xattr_free(struct xattr_array *vals, size_t sz); | |
219 | +void xheader_xattr_copy(const struct tar_stat_info *st, | |
220 | + struct xattr_array **vals, size_t *sz); | |
221 | +void xheader_xattr_add(struct tar_stat_info *st, | |
222 | + const char *key, const char *val, size_t len); | |
223 | ||
224 | /* Module system.c */ | |
225 | ||
bd523de6 MT |
226 | diff -urNp tar-1.24-orig/src/create.c tar-1.24/src/create.c |
227 | --- tar-1.24-orig/src/create.c 2010-10-24 20:07:54.000000000 +0200 | |
228 | +++ tar-1.24/src/create.c 2010-10-25 10:24:52.560213618 +0200 | |
547b54ef MT |
229 | @@ -24,6 +24,7 @@ |
230 | #include <quotearg.h> | |
231 | ||
232 | #include "common.h" | |
233 | + | |
234 | #include <hash.h> | |
235 | ||
bd523de6 MT |
236 | /* Error number to use when an impostor is discovered. |
237 | @@ -934,6 +935,30 @@ start_header (struct tar_stat_info *st) | |
547b54ef MT |
238 | GNAME_TO_CHARS (st->gname, header->header.gname); |
239 | } | |
240 | ||
241 | + if (archive_format == POSIX_FORMAT) | |
242 | + { | |
243 | + if (acls_option > 0) | |
244 | + { | |
245 | + if (st->acls_a_ptr) | |
246 | + xheader_store ("SCHILY.acl.access", st, NULL); | |
247 | + if (st->acls_d_ptr) | |
248 | + xheader_store ("SCHILY.acl.default", st, NULL); | |
249 | + } | |
250 | + if ((selinux_context_option > 0) && st->cntx_name) | |
251 | + xheader_store ("RHT.security.selinux", st, NULL); | |
252 | + if (xattrs_option > 0) | |
253 | + { | |
254 | + size_t scan_xattr = 0; | |
255 | + struct xattr_array *xattr_map = st->xattr_map; | |
9f0833cd | 256 | + |
547b54ef MT |
257 | + while (scan_xattr < st->xattr_map_size) |
258 | + { | |
259 | + xheader_store (xattr_map[scan_xattr].xkey, st, &scan_xattr); | |
260 | + ++scan_xattr; | |
261 | + } | |
262 | + } | |
263 | + } | |
264 | + | |
265 | return header; | |
266 | } | |
267 | ||
bd523de6 MT |
268 | @@ -1709,6 +1734,10 @@ dump_file0 (struct tar_stat_info *st, ch |
269 | bool ok; | |
270 | struct stat final_stat; | |
547b54ef MT |
271 | |
272 | + xattrs_acls_get(st, p, fd, !is_dir); | |
273 | + xattrs_selinux_get(st, p, fd); | |
274 | + xattrs_xattrs_get(st, p, fd); | |
275 | + | |
276 | if (is_dir) | |
277 | { | |
278 | const char *tag_file_name; | |
bd523de6 | 279 | @@ -1826,6 +1855,9 @@ dump_file0 (struct tar_stat_info *st, ch |
9f0833cd MT |
280 | if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size) |
281 | write_long_link (st); | |
282 | ||
283 | + xattrs_selinux_get(st, p, -1); | |
284 | + xattrs_xattrs_get(st, p, -1); | |
285 | + | |
286 | block_ordinal = current_block_ordinal (); | |
287 | st->stat.st_size = 0; /* force 0 size on symlink */ | |
288 | header = start_header (st); | |
bd523de6 MT |
289 | @@ -1844,11 +1876,23 @@ dump_file0 (struct tar_stat_info *st, ch |
290 | } | |
291 | #endif | |
292 | else if (S_ISCHR (st->stat.st_mode)) | |
293 | - type = CHRTYPE; | |
294 | + { | |
295 | + type = CHRTYPE; | |
296 | + xattrs_selinux_get(st, p, -1); | |
297 | + xattrs_xattrs_get(st, p, -1); | |
298 | + } | |
299 | else if (S_ISBLK (st->stat.st_mode)) | |
300 | - type = BLKTYPE; | |
301 | + { | |
302 | + type = BLKTYPE; | |
303 | + xattrs_selinux_get(st, p, -1); | |
304 | + xattrs_xattrs_get(st, p, -1); | |
305 | + } | |
306 | else if (S_ISFIFO (st->stat.st_mode)) | |
307 | - type = FIFOTYPE; | |
308 | + { | |
309 | + type = FIFOTYPE; | |
310 | + xattrs_selinux_get(st, p, -1); | |
311 | + xattrs_xattrs_get(st, p, -1); | |
312 | + } | |
313 | else if (S_ISSOCK (st->stat.st_mode)) | |
314 | { | |
315 | WARNOPT (WARN_FILE_IGNORED, | |
316 | diff -urNp tar-1.24-orig/src/extract.c tar-1.24/src/extract.c | |
317 | --- tar-1.24-orig/src/extract.c 2010-10-24 20:07:54.000000000 +0200 | |
318 | +++ tar-1.24/src/extract.c 2010-10-25 10:35:10.903214037 +0200 | |
319 | @@ -97,6 +97,14 @@ struct delayed_set_stat | |
320 | /* Directory that the name is relative to. */ | |
321 | int change_dir; | |
322 | ||
323 | + /* extended attributes*/ | |
547b54ef MT |
324 | + char *cntx_name; |
325 | + char *acls_a_ptr; | |
326 | + size_t acls_a_len; | |
327 | + char *acls_d_ptr; | |
328 | + size_t acls_d_len; | |
329 | + size_t xattr_map_size; /* Size of the xattr map */ | |
330 | + struct xattr_array *xattr_map; | |
bd523de6 MT |
331 | /* Length and contents of name. */ |
332 | size_t file_name_len; | |
547b54ef | 333 | char file_name[1]; |
bd523de6 | 334 | @@ -134,6 +142,18 @@ struct delayed_link |
547b54ef MT |
335 | hard-linked together. */ |
336 | struct string_list *sources; | |
337 | ||
338 | + /* SELinux context */ | |
339 | + char *cntx_name; | |
9f0833cd | 340 | + |
547b54ef MT |
341 | + /* ACLs */ |
342 | + char *acls_a_ptr; | |
343 | + size_t acls_a_len; | |
344 | + char *acls_d_ptr; | |
345 | + size_t acls_d_len; | |
9f0833cd | 346 | + |
547b54ef MT |
347 | + size_t xattr_map_size; /* Size of the xattr map */ |
348 | + struct xattr_array *xattr_map; | |
9f0833cd | 349 | + |
547b54ef MT |
350 | /* The desired target of the desired link. */ |
351 | char target[1]; | |
352 | }; | |
bd523de6 MT |
353 | @@ -335,6 +355,10 @@ set_stat (char const *file_name, |
354 | utime_error (file_name); | |
547b54ef MT |
355 | } |
356 | ||
357 | + xattrs_acls_set(st, file_name, typeflag); | |
358 | + xattrs_selinux_set(st, file_name, typeflag); | |
359 | + xattrs_xattrs_set(st, file_name, typeflag); | |
360 | + | |
bd523de6 | 361 | if (0 < same_owner_option && ! interdir) |
547b54ef | 362 | { |
bd523de6 MT |
363 | /* Some systems allow non-root users to give files away. Once this |
364 | @@ -431,6 +455,36 @@ delay_set_stat (char const *file_name, s | |
365 | data->atflag = atflag; | |
547b54ef | 366 | data->after_links = 0; |
bd523de6 | 367 | data->change_dir = chdir_current; |
547b54ef | 368 | + data->cntx_name = NULL; |
bd523de6 MT |
369 | + if (st) |
370 | + assign_string (&data->cntx_name, st->cntx_name); | |
371 | + if (st && st->acls_a_ptr) | |
547b54ef MT |
372 | + { |
373 | + data->acls_a_ptr = xmemdup(st->acls_a_ptr, st->acls_a_len + 1); | |
374 | + data->acls_a_len = st->acls_a_len; | |
375 | + } | |
376 | + else | |
377 | + { | |
378 | + data->acls_a_ptr = NULL; | |
379 | + data->acls_a_len = 0; | |
380 | + } | |
bd523de6 | 381 | + if (st && st->acls_d_ptr) |
547b54ef MT |
382 | + { |
383 | + data->acls_d_ptr = xmemdup(st->acls_d_ptr, st->acls_d_len + 1); | |
384 | + data->acls_d_len = st->acls_d_len; | |
385 | + } | |
386 | + else | |
387 | + { | |
388 | + data->acls_d_ptr = NULL; | |
389 | + data->acls_d_len = 0; | |
390 | + } | |
bd523de6 MT |
391 | + if (st) |
392 | + xheader_xattr_copy (st, &data->xattr_map, &data->xattr_map_size); | |
393 | + else | |
394 | + { | |
395 | + data->xattr_map = NULL; | |
396 | + data->xattr_map_size = 0; | |
397 | + } | |
547b54ef MT |
398 | strcpy (data->file_name, file_name); |
399 | delayed_set_stat_head = data; | |
bd523de6 MT |
400 | if (must_be_dot_or_slash (file_name)) |
401 | @@ -661,6 +708,31 @@ maybe_recoverable (char *file_name, bool | |
402 | return RECOVER_NO; | |
9f0833cd MT |
403 | } |
404 | ||
405 | +/* Restore stat extended attributes (xattr) for FILE_NAME, using information | |
406 | + given in *ST. Restore before extraction because they may affect layout. | |
407 | + If not restoring permissions, invert the | |
408 | + INVERT_PERMISSIONS bits from the file's current permissions. | |
409 | + TYPEFLAG specifies the type of the file. | |
410 | + FILE_CREATED indicates set_xattr has created the file */ | |
411 | +static int | |
412 | +set_xattr (char const *file_name, struct tar_stat_info const *st, | |
413 | + mode_t invert_permissions, char typeflag, int *file_created) | |
414 | +{ | |
415 | + int status = 0; | |
bd523de6 | 416 | + bool interdir_made = false; |
9f0833cd MT |
417 | + |
418 | + if ((xattrs_option >= 0) && st->xattr_map_size) { | |
419 | + mode_t mode = current_stat_info.stat.st_mode & MODE_RWX & ~ current_umask; | |
420 | + | |
421 | + do | |
422 | + status = mknod (file_name, mode ^ invert_permissions, 0); | |
bd523de6 | 423 | + while (status && maybe_recoverable ((char *)file_name, false, &interdir_made)); |
9f0833cd MT |
424 | + xattrs_xattrs_set(st, file_name, typeflag); |
425 | + *file_created = 1; | |
426 | + } | |
427 | + return(status); | |
428 | +} | |
429 | + | |
430 | /* Fix the statuses of all directories whose statuses need fixing, and | |
431 | which are not ancestors of FILE_NAME. If AFTER_LINKS is | |
432 | nonzero, do this for all such directories; otherwise, stop at the | |
bd523de6 | 433 | @@ -721,12 +793,23 @@ apply_nonancestor_delayed_set_stat (char |
547b54ef MT |
434 | sb.stat.st_gid = data->gid; |
435 | sb.atime = data->atime; | |
436 | sb.mtime = data->mtime; | |
bd523de6 MT |
437 | + sb.cntx_name = data->cntx_name; |
438 | + sb.acls_a_ptr = data->acls_a_ptr; | |
439 | + sb.acls_a_len = data->acls_a_len; | |
440 | + sb.acls_d_ptr = data->acls_d_ptr; | |
441 | + sb.acls_d_len = data->acls_d_len; | |
442 | + sb.xattr_map = data->xattr_map; | |
443 | + sb.xattr_map_size = data->xattr_map_size; | |
444 | set_stat (data->file_name, &sb, | |
445 | -1, current_mode, current_mode_mask, | |
446 | DIRTYPE, data->interdir, data->atflag); | |
547b54ef MT |
447 | } |
448 | ||
449 | delayed_set_stat_head = data->next; | |
450 | + xheader_xattr_free (data->xattr_map, data->xattr_map_size); | |
451 | + free (data->cntx_name); | |
452 | + free (data->acls_a_ptr); | |
453 | + free (data->acls_d_ptr); | |
454 | free (data); | |
455 | } | |
456 | } | |
bd523de6 | 457 | @@ -842,6 +925,7 @@ extract_dir (char *file_name, int typefl |
9f0833cd MT |
458 | |
459 | static int | |
bd523de6 MT |
460 | open_output_file (char const *file_name, int typeflag, mode_t mode, |
461 | + int file_created, | |
462 | mode_t *current_mode, mode_t *current_mode_mask) | |
9f0833cd MT |
463 | { |
464 | int fd; | |
bd523de6 MT |
465 | @@ -852,6 +936,10 @@ open_output_file (char const *file_name, |
466 | ? O_TRUNC | (dereference_option ? 0 : O_NOFOLLOW) | |
9f0833cd MT |
467 | : O_EXCL)); |
468 | ||
469 | + /* File might be created in set_xattr. So clear O_EXCL to avoid open() failure */ | |
470 | + if (file_created) | |
471 | + openflag = openflag & ~O_EXCL; | |
472 | + | |
bd523de6 MT |
473 | if (typeflag == CONTTYPE) |
474 | { | |
475 | static int conttype_diagnosed; | |
476 | @@ -908,6 +996,7 @@ extract_file (char *file_name, int typef | |
477 | bool interdir_made = false; | |
478 | mode_t mode = (current_stat_info.stat.st_mode & MODE_RWX | |
479 | & ~ (0 < same_owner_option ? S_IRWXG | S_IRWXO : 0)); | |
480 | + mode_t invert_permissions = 0 < same_owner_option ? mode & (S_IRWXG | S_IRWXO) : 0; | |
481 | mode_t current_mode = 0; | |
482 | mode_t current_mode_mask = 0; | |
483 | ||
484 | @@ -924,7 +1013,17 @@ extract_file (char *file_name, int typef | |
485 | } | |
9f0833cd MT |
486 | else |
487 | { | |
9f0833cd MT |
488 | + int file_created = 0; |
489 | + if (set_xattr (file_name, ¤t_stat_info, invert_permissions, | |
490 | + typeflag, &file_created)) | |
491 | + { | |
492 | + skip_member (); | |
493 | + open_error (file_name); | |
494 | + return 1; | |
495 | + } | |
496 | + | |
bd523de6 MT |
497 | while ((fd = open_output_file (file_name, typeflag, mode, |
498 | + file_created, | |
499 | ¤t_mode, ¤t_mode_mask)) | |
500 | < 0) | |
501 | { | |
502 | @@ -1065,6 +1164,13 @@ create_placeholder_file (char *file_name | |
547b54ef MT |
503 | + strlen (file_name) + 1); |
504 | p->sources->next = 0; | |
505 | strcpy (p->sources->string, file_name); | |
506 | + p->cntx_name = NULL; | |
9f0833cd | 507 | + assign_string (&p->cntx_name, current_stat_info.cntx_name); |
547b54ef MT |
508 | + p->acls_a_ptr = NULL; |
509 | + p->acls_a_len = 0; | |
510 | + p->acls_d_ptr = NULL; | |
511 | + p->acls_d_len = 0; | |
9f0833cd | 512 | + xheader_xattr_copy (¤t_stat_info, &p->xattr_map, &p->xattr_map_size); |
547b54ef MT |
513 | strcpy (p->target, current_stat_info.link_name); |
514 | ||
515 | h = delayed_set_stat_head; | |
bd523de6 | 516 | @@ -1499,6 +1605,13 @@ apply_delayed_links (void) |
547b54ef | 517 | st1.stat.st_gid = ds->gid; |
bd523de6 MT |
518 | st1.atime = ds->atime; |
519 | st1.mtime = ds->mtime; | |
547b54ef MT |
520 | + st1.cntx_name = ds->cntx_name; |
521 | + st1.acls_a_ptr = ds->acls_a_ptr; | |
522 | + st1.acls_a_len = ds->acls_a_len; | |
523 | + st1.acls_d_ptr = ds->acls_d_ptr; | |
524 | + st1.acls_d_len = ds->acls_d_len; | |
525 | + st1.xattr_map = ds->xattr_map; | |
526 | + st1.xattr_map_size = ds->xattr_map_size; | |
bd523de6 MT |
527 | set_stat (source, &st1, -1, 0, 0, SYMTYPE, |
528 | false, AT_SYMLINK_NOFOLLOW); | |
547b54ef | 529 | valid_source = source; |
bd523de6 | 530 | @@ -1513,6 +1626,9 @@ apply_delayed_links (void) |
9f0833cd MT |
531 | sources = next; |
532 | } | |
533 | ||
534 | + xheader_xattr_free (ds->xattr_map, ds->xattr_map_size); | |
535 | + free (ds->cntx_name); | |
536 | + | |
537 | { | |
538 | struct delayed_link *next = ds->next; | |
539 | free (ds); | |
bd523de6 MT |
540 | diff -urNp tar-1.24-orig/src/list.c tar-1.24/src/list.c |
541 | --- tar-1.24-orig/src/list.c 2010-10-25 09:15:14.216463863 +0200 | |
542 | +++ tar-1.24/src/list.c 2010-10-25 10:24:52.563213968 +0200 | |
543 | @@ -597,6 +597,13 @@ decode_header (union block *header, stru | |
547b54ef MT |
544 | assign_string (&stat_info->gname, |
545 | header->header.gname[0] ? header->header.gname : NULL); | |
546 | ||
547 | + stat_info->acls_a_ptr = NULL; | |
548 | + stat_info->acls_a_len = 0; | |
549 | + stat_info->acls_d_ptr = NULL; | |
550 | + stat_info->acls_d_len = 0; | |
551 | + stat_info->cntx_name = NULL; | |
552 | + xheader_xattr_init(stat_info); | |
9f0833cd | 553 | + |
547b54ef MT |
554 | if (format == OLDGNU_FORMAT && incremental_option) |
555 | { | |
556 | stat_info->atime.tv_sec = TIME_FROM_HEADER (header->oldgnu_header.atime); | |
bd523de6 MT |
557 | diff -urNp tar-1.24-orig/src/Makefile.am tar-1.24/src/Makefile.am |
558 | --- tar-1.24-orig/src/Makefile.am 2010-10-24 20:07:54.000000000 +0200 | |
559 | +++ tar-1.24/src/Makefile.am 2010-10-25 10:24:52.564214456 +0200 | |
547b54ef MT |
560 | @@ -20,7 +20,7 @@ |
561 | ||
562 | bin_PROGRAMS = tar | |
563 | ||
564 | -noinst_HEADERS = arith.h common.h tar.h | |
565 | +noinst_HEADERS = arith.h common.h tar.h xattrs.h | |
566 | tar_SOURCES = \ | |
567 | buffer.c\ | |
568 | checkpoint.c\ | |
9f0833cd MT |
569 | @@ -42,10 +42,11 @@ tar_SOURCES = \ |
570 | unlink.c\ | |
547b54ef | 571 | update.c\ |
9f0833cd MT |
572 | utf8.c\ |
573 | - warning.c | |
574 | + warning.c\ | |
547b54ef MT |
575 | + xattrs.c |
576 | ||
9f0833cd | 577 | INCLUDES = -I$(top_srcdir)/gnu -I../ -I../gnu -I$(top_srcdir)/lib -I../lib |
547b54ef | 578 | |
9f0833cd | 579 | LDADD = ../lib/libtar.a ../gnu/libgnu.a $(LIBINTL) $(LIBICONV) |
547b54ef | 580 | |
bd523de6 MT |
581 | -tar_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS) |
582 | +tar_LDADD = $(LIBS) $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS) | |
583 | diff -urNp tar-1.24-orig/src/tar.c tar-1.24/src/tar.c | |
584 | --- tar-1.24-orig/src/tar.c 2010-10-24 20:07:55.000000000 +0200 | |
585 | +++ tar-1.24/src/tar.c 2010-10-25 10:24:52.565223676 +0200 | |
9f0833cd | 586 | @@ -255,7 +255,8 @@ tar_set_quoting_style (char *arg) |
547b54ef MT |
587 | |
588 | enum | |
589 | { | |
590 | - ANCHORED_OPTION = CHAR_MAX + 1, | |
591 | + ACLS_OPTION = CHAR_MAX + 1, | |
592 | + ANCHORED_OPTION, | |
593 | ATIME_PRESERVE_OPTION, | |
594 | BACKUP_OPTION, | |
595 | CHECK_DEVICE_OPTION, | |
bd523de6 | 596 | @@ -288,6 +289,7 @@ enum |
547b54ef MT |
597 | MODE_OPTION, |
598 | MTIME_OPTION, | |
599 | NEWER_MTIME_OPTION, | |
600 | + NO_ACLS_OPTION, | |
601 | NO_ANCHORED_OPTION, | |
602 | NO_AUTO_COMPRESS_OPTION, | |
603 | NO_CHECK_DEVICE_OPTION, | |
bd523de6 | 604 | @@ -301,9 +303,11 @@ enum |
547b54ef MT |
605 | NO_SAME_OWNER_OPTION, |
606 | NO_SAME_PERMISSIONS_OPTION, | |
9f0833cd | 607 | NO_SEEK_OPTION, |
547b54ef MT |
608 | + NO_SELINUX_CONTEXT_OPTION, |
609 | NO_UNQUOTE_OPTION, | |
610 | NO_WILDCARDS_MATCH_SLASH_OPTION, | |
611 | NO_WILDCARDS_OPTION, | |
612 | + NO_XATTR_OPTION, | |
613 | NULL_OPTION, | |
614 | NUMERIC_OWNER_OPTION, | |
615 | OCCURRENCE_OPTION, | |
bd523de6 | 616 | @@ -325,6 +329,7 @@ enum |
547b54ef MT |
617 | RMT_COMMAND_OPTION, |
618 | RSH_COMMAND_OPTION, | |
619 | SAME_OWNER_OPTION, | |
620 | + SELINUX_CONTEXT_OPTION, | |
621 | SHOW_DEFAULTS_OPTION, | |
622 | SHOW_OMITTED_DIRS_OPTION, | |
623 | SHOW_TRANSFORMED_NAMES_OPTION, | |
bd523de6 | 624 | @@ -340,7 +345,8 @@ enum |
547b54ef | 625 | VOLNO_FILE_OPTION, |
bd523de6 | 626 | WARNING_OPTION, |
547b54ef MT |
627 | WILDCARDS_MATCH_SLASH_OPTION, |
628 | - WILDCARDS_OPTION | |
629 | + WILDCARDS_OPTION, | |
630 | + XATTR_OPTION | |
631 | }; | |
632 | ||
633 | const char *argp_program_version = "tar (" PACKAGE_NAME ") " VERSION; | |
bd523de6 | 634 | @@ -486,6 +492,10 @@ static struct argp_option options[] = { |
547b54ef MT |
635 | {NULL, 0, NULL, 0, |
636 | N_("Handling of file attributes:"), GRID }, | |
637 | ||
9f0833cd | 638 | + {"acls", ACLS_OPTION, 0, 0, |
547b54ef | 639 | + N_("Save the ACLs to the archive"), GRID+1 }, |
9f0833cd | 640 | + {"no-acls", NO_ACLS_OPTION, 0, 0, |
547b54ef MT |
641 | + N_("Don't extract the ACLs from the archive"), GRID+1 }, |
642 | {"owner", OWNER_OPTION, N_("NAME"), 0, | |
643 | N_("force NAME as owner for added files"), GRID+1 }, | |
644 | {"group", GROUP_OPTION, N_("NAME"), 0, | |
bd523de6 | 645 | @@ -516,6 +526,14 @@ static struct argp_option options[] = { |
547b54ef MT |
646 | {"preserve-order", 's', 0, 0, |
647 | N_("sort names to extract to match archive"), GRID+1 }, | |
648 | {"same-order", 0, 0, OPTION_ALIAS, NULL, GRID+1 }, | |
9f0833cd | 649 | + {"selinux", SELINUX_CONTEXT_OPTION, 0, 0, |
547b54ef | 650 | + N_("Save the SELinux context to the archive"), GRID+1 }, |
9f0833cd | 651 | + {"no-selinux", NO_SELINUX_CONTEXT_OPTION, 0, 0, |
547b54ef | 652 | + N_("Don't extract the SELinux context from the archive"), GRID+1 }, |
9f0833cd | 653 | + {"xattrs", XATTR_OPTION, 0, 0, |
547b54ef | 654 | + N_("Save the user/root xattrs to the archive"), GRID+1 }, |
9f0833cd | 655 | + {"no-xattrs", NO_XATTR_OPTION, 0, 0, |
547b54ef MT |
656 | + N_("Don't extract the user/root xattrs from the archive"), GRID+1 }, |
657 | {"preserve", PRESERVE_OPTION, 0, 0, | |
658 | N_("same as both -p and -s"), GRID+1 }, | |
659 | {"delay-directory-restore", DELAY_DIRECTORY_RESTORE_OPTION, 0, 0, | |
bd523de6 | 660 | @@ -2079,6 +2097,37 @@ parse_opt (int key, char *arg, struct ar |
547b54ef MT |
661 | same_permissions_option = -1; |
662 | break; | |
663 | ||
664 | + case ACLS_OPTION: | |
665 | + set_archive_format ("posix"); | |
666 | + acls_option = 1; | |
667 | + break; | |
668 | + | |
669 | + case NO_ACLS_OPTION: | |
670 | + acls_option = -1; | |
671 | + break; | |
672 | + | |
673 | + case SELINUX_CONTEXT_OPTION: | |
674 | + set_archive_format ("posix"); | |
675 | + selinux_context_option = 1; | |
676 | + break; | |
677 | + | |
678 | + case NO_SELINUX_CONTEXT_OPTION: | |
679 | + selinux_context_option = -1; | |
680 | + break; | |
681 | + | |
682 | + case XATTR_OPTION: | |
683 | + set_archive_format ("posix"); | |
684 | + if (!acls_option) acls_option = 1; | |
685 | + if (!selinux_context_option) selinux_context_option = 1; | |
686 | + xattrs_option = 1; | |
687 | + break; | |
688 | + | |
689 | + case NO_XATTR_OPTION: | |
690 | + if (!acls_option) acls_option = -1; | |
691 | + if (!selinux_context_option) selinux_context_option = -1; | |
692 | + xattrs_option = -1; | |
693 | + break; | |
694 | + | |
695 | case RECURSION_OPTION: | |
696 | recursion_option = FNM_LEADING_DIR; | |
697 | break; | |
bd523de6 | 698 | @@ -2461,6 +2510,29 @@ decode_options (int argc, char **argv) |
547b54ef MT |
699 | || subcommand_option != LIST_SUBCOMMAND)) |
700 | USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives"))); | |
701 | ||
702 | + /* star create's non-POSIX typed archives with xattr support, so allow the | |
703 | + extra headers */ | |
704 | + if ((acls_option > 0) | |
705 | + && archive_format != POSIX_FORMAT | |
706 | + && (subcommand_option != EXTRACT_SUBCOMMAND | |
707 | + || subcommand_option != DIFF_SUBCOMMAND | |
708 | + || subcommand_option != LIST_SUBCOMMAND)) | |
709 | + USAGE_ERROR ((0, 0, _("--acls can be used only on POSIX archives"))); | |
710 | + | |
711 | + if ((selinux_context_option > 0) | |
712 | + && archive_format != POSIX_FORMAT | |
713 | + && (subcommand_option != EXTRACT_SUBCOMMAND | |
714 | + || subcommand_option != DIFF_SUBCOMMAND | |
715 | + || subcommand_option != LIST_SUBCOMMAND)) | |
716 | + USAGE_ERROR ((0, 0, _("--selinux can be used only on POSIX archives"))); | |
717 | + | |
718 | + if ((xattrs_option > 0) | |
719 | + && archive_format != POSIX_FORMAT | |
720 | + && (subcommand_option != EXTRACT_SUBCOMMAND | |
721 | + || subcommand_option != DIFF_SUBCOMMAND | |
722 | + || subcommand_option != LIST_SUBCOMMAND)) | |
723 | + USAGE_ERROR ((0, 0, _("--xattrs can be used only on POSIX archives"))); | |
724 | + | |
725 | /* If ready to unlink hierarchies, so we are for simpler files. */ | |
726 | if (recursive_unlink_option) | |
727 | old_files_option = UNLINK_FIRST_OLD_FILES; | |
bd523de6 | 728 | @@ -2713,11 +2785,15 @@ void |
547b54ef MT |
729 | tar_stat_destroy (struct tar_stat_info *st) |
730 | { | |
bd523de6 | 731 | tar_stat_close (st); |
547b54ef MT |
732 | + xheader_xattr_free (st->xattr_map, st->xattr_map_size); |
733 | free (st->orig_file_name); | |
734 | free (st->file_name); | |
735 | free (st->link_name); | |
736 | free (st->uname); | |
737 | free (st->gname); | |
738 | + free (st->cntx_name); | |
739 | + free (st->acls_a_ptr); | |
740 | + free (st->acls_d_ptr); | |
741 | free (st->sparse_map); | |
742 | free (st->dumpdir); | |
743 | xheader_destroy (&st->xhdr); | |
bd523de6 MT |
744 | diff -urNp tar-1.24-orig/src/tar.h tar-1.24/src/tar.h |
745 | --- tar-1.24-orig/src/tar.h 2010-10-24 20:07:46.000000000 +0200 | |
746 | +++ tar-1.24/src/tar.h 2010-10-25 10:24:52.567223606 +0200 | |
547b54ef MT |
747 | @@ -276,6 +276,14 @@ struct xheader |
748 | uintmax_t string_length; | |
749 | }; | |
750 | ||
751 | +/* Information about xattrs for a file. */ | |
752 | +struct xattr_array | |
753 | + { | |
754 | + char *xkey; | |
755 | + char *xval_ptr; | |
756 | + size_t xval_len; | |
757 | + }; | |
758 | + | |
759 | struct tar_stat_info | |
760 | { | |
761 | char *orig_file_name; /* name of file read from the archive header */ | |
762 | @@ -287,6 +295,15 @@ struct tar_stat_info | |
763 | ||
764 | char *uname; /* user name of owner */ | |
765 | char *gname; /* group name of owner */ | |
766 | + | |
767 | + char *cntx_name; /* SELinux context for the current archive entry. */ | |
768 | + | |
769 | + char *acls_a_ptr; /* Access ACLs for the current archive entry. */ | |
770 | + size_t acls_a_len; /* Access ACLs for the current archive entry. */ | |
9f0833cd | 771 | + |
547b54ef MT |
772 | + char *acls_d_ptr; /* Default ACLs for the current archive entry. */ |
773 | + size_t acls_d_len; /* Default ACLs for the current archive entry. */ | |
774 | + | |
775 | struct stat stat; /* regular filesystem stat */ | |
776 | ||
777 | /* STAT doesn't always have access, data modification, and status | |
778 | @@ -309,6 +326,9 @@ struct tar_stat_info | |
779 | size_t sparse_map_size; /* Size of the sparse map */ | |
780 | struct sp_array *sparse_map; | |
781 | ||
782 | + size_t xattr_map_size; /* Size of the xattr map */ | |
783 | + struct xattr_array *xattr_map; | |
784 | + | |
785 | /* Extended headers */ | |
786 | struct xheader xhdr; | |
bd523de6 MT |
787 | |
788 | diff -urNp tar-1.24-orig/src/xattrs.c tar-1.24/src/xattrs.c | |
789 | --- tar-1.24-orig/src/xattrs.c 1970-01-01 01:00:00.000000000 +0100 | |
790 | +++ tar-1.24/src/xattrs.c 2010-10-25 10:24:52.568214736 +0200 | |
791 | @@ -0,0 +1,489 @@ | |
547b54ef MT |
792 | +/* Create a tar archive. |
793 | + | |
794 | + Copyright (C) 2006 Free Software Foundation, Inc. | |
795 | + | |
796 | + Written by James Antill, on 2006-07-27. | |
797 | + | |
798 | + This program is free software; you can redistribute it and/or modify it | |
799 | + under the terms of the GNU General Public License as published by the | |
800 | + Free Software Foundation; either version 2, or (at your option) any later | |
801 | + version. | |
802 | + | |
803 | + This program is distributed in the hope that it will be useful, but | |
804 | + WITHOUT ANY WARRANTY; without even the implied warranty of | |
805 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | |
806 | + Public License for more details. | |
807 | + | |
808 | + You should have received a copy of the GNU General Public License along | |
809 | + with this program; if not, write to the Free Software Foundation, Inc., | |
810 | + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ | |
811 | + | |
812 | +#include <system.h> | |
813 | + | |
814 | +#include <quotearg.h> | |
815 | + | |
816 | +#include "common.h" | |
817 | + | |
818 | + | |
819 | +#ifndef HAVE_SELINUX_SELINUX_H | |
820 | +# undef HAVE_LIBSELINUX | |
821 | +#endif | |
822 | + | |
823 | +#ifndef HAVE_ATTR_XATTR_H | |
824 | +# undef HAVE_XATTRS | |
825 | +#endif | |
826 | + | |
827 | +#ifndef HAVE_SYS_ACL_H | |
828 | +# undef HAVE_LIBACL | |
829 | +#endif | |
830 | + | |
831 | +#ifdef HAVE_SELINUX_SELINUX_H | |
832 | +# include <selinux/selinux.h> | |
833 | +#endif | |
834 | + | |
835 | +#ifdef HAVE_ATTR_XATTR_H | |
836 | +# include <attr/xattr.h> | |
837 | +#endif | |
838 | + | |
839 | +#ifdef HAVE_SYS_ACL_H | |
840 | +# include <sys/acl.h> | |
841 | +#endif | |
842 | + | |
843 | + | |
844 | +#if 0 /* unused by xattr's atm. */ | |
845 | +static void xattrs__fd_get(struct tar_stat_info *st, | |
846 | + char const *file_name, int fd, const char *attr, | |
847 | + char **ret_ptr, size_t *ret_len) | |
848 | +{ | |
849 | +#ifdef HAVE_XATTRS | |
850 | + static ssize_t asz = 1024; | |
851 | + ssize_t ret = 0; | |
852 | + static char *val = NULL; | |
9f0833cd | 853 | + |
547b54ef | 854 | + if (!val) val = xmalloc (asz); |
9f0833cd | 855 | + |
547b54ef MT |
856 | + while (((ret = fgetxattr (fd, attr, val, asz)) == -1) && |
857 | + (errno == ERANGE)) | |
858 | + { | |
859 | + asz <<= 1; | |
860 | + val = xrealloc (val, asz); | |
861 | + } | |
9f0833cd | 862 | + |
547b54ef MT |
863 | + if (ret != -1) |
864 | + { | |
865 | + *ret_ptr = xmemdup (val, ret + 1); | |
866 | + *ret_len = ret; | |
867 | + } | |
868 | + else if (errno != ENOATTR) | |
869 | + call_arg_warn ("fgetxattr", file_name); | |
870 | +#endif | |
871 | +} | |
872 | +#endif | |
873 | + | |
874 | +static void xattrs__acls_get_a(struct tar_stat_info *st, | |
875 | + char const *file_name, int fd, | |
876 | + char **ret_ptr, size_t *ret_len) | |
877 | +{ /* "system.posix_acl_access" */ | |
878 | +#ifdef HAVE_LIBACL | |
879 | + char *val = NULL; | |
880 | + ssize_t len; | |
881 | + acl_t acl; | |
882 | + | |
883 | + if (fd != -1) | |
884 | + { | |
885 | + if ((acl = acl_get_fd (fd)) == (acl_t)NULL) | |
886 | + { | |
887 | + if (errno != ENOTSUP) | |
888 | + call_arg_warn ("acl_get_fd", file_name); | |
889 | + return; | |
890 | + } | |
891 | + } | |
892 | + else if ((acl = acl_get_file (file_name, ACL_TYPE_ACCESS)) == (acl_t)NULL) | |
893 | + { | |
894 | + if (errno != ENOTSUP) | |
895 | + call_arg_warn ("acl_get_file", file_name); | |
896 | + return; | |
897 | + } | |
9f0833cd MT |
898 | + |
899 | + | |
547b54ef MT |
900 | + val = acl_to_text(acl, &len); |
901 | + acl_free (acl); | |
9f0833cd | 902 | + |
547b54ef MT |
903 | + if (val == NULL) |
904 | + { | |
905 | + call_arg_warn ("acl_to_text", file_name); | |
906 | + return; | |
907 | + } | |
9f0833cd | 908 | + |
547b54ef MT |
909 | + *ret_ptr = xstrdup (val); |
910 | + *ret_len = len; | |
9f0833cd | 911 | + |
547b54ef MT |
912 | + acl_free (val); |
913 | +#endif | |
914 | +} | |
915 | + | |
916 | +static void xattrs__acls_get_d(struct tar_stat_info *st, | |
917 | + char const *file_name, | |
918 | + char **ret_ptr, size_t *ret_len) | |
919 | +{ /* "system.posix_acl_default" */ | |
920 | +#ifdef HAVE_LIBACL | |
921 | + char *val = NULL; | |
922 | + ssize_t len; | |
923 | + acl_t acl; | |
9f0833cd | 924 | + |
547b54ef MT |
925 | + if ((acl = acl_get_file (file_name, ACL_TYPE_DEFAULT)) == (acl_t)NULL) |
926 | + { | |
927 | + if (errno != ENOTSUP) | |
928 | + call_arg_warn ("acl_get_file", file_name); | |
929 | + return; | |
930 | + } | |
9f0833cd | 931 | + |
547b54ef MT |
932 | + val = acl_to_text(acl, &len); |
933 | + acl_free (acl); | |
9f0833cd | 934 | + |
547b54ef MT |
935 | + if (val == NULL) |
936 | + { | |
937 | + call_arg_warn ("acl_to_text", file_name); | |
938 | + return; | |
939 | + } | |
9f0833cd | 940 | + |
547b54ef MT |
941 | + *ret_ptr = xstrdup (val); |
942 | + *ret_len = len; | |
9f0833cd | 943 | + |
547b54ef MT |
944 | + acl_free (val); |
945 | +#endif | |
946 | +} | |
947 | + | |
948 | +void xattrs_acls_get(struct tar_stat_info *st, char const *file_name, int fd, | |
949 | + int xisfile) | |
950 | +{ | |
951 | + if (acls_option > 0) | |
952 | + { | |
953 | +#ifndef HAVE_LIBACL | |
954 | + static int done = 0; | |
955 | + if (!done) | |
956 | + WARN ((0, 0, _("ACL support requested, but not available"))); | |
957 | + done = 1; | |
958 | +#endif | |
959 | + xattrs__acls_get_a (st, file_name, fd, | |
960 | + &st->acls_a_ptr, &st->acls_a_len); | |
961 | + if (!xisfile) | |
962 | + xattrs__acls_get_d (st, file_name, | |
963 | + &st->acls_d_ptr, &st->acls_d_len); | |
964 | + } | |
965 | +} | |
966 | + | |
967 | +void xattrs_selinux_get(struct tar_stat_info *st, char const *file_name, int fd) | |
968 | +{ | |
969 | + if (selinux_context_option > 0) | |
970 | + { | |
971 | +#ifndef HAVE_LIBSELINUX | |
972 | + static int done = 0; | |
973 | + if (!done) | |
974 | + WARN ((0, 0, _("SELinux support requested, but not available"))); | |
975 | + done = 1; | |
976 | +#else | |
977 | + if (fd == -1) | |
978 | + { | |
979 | + if ((lgetfilecon (file_name, &st->cntx_name) == -1) && (errno != ENOTSUP) && (errno != ENODATA)) | |
980 | + call_arg_warn ("lgetfilecon", file_name); | |
981 | + } | |
982 | + else if ((fgetfilecon (fd, &st->cntx_name) == -1) && (errno != ENOTSUP) && (errno != ENODATA)) | |
983 | + call_arg_warn ("fgetfilecon", file_name); | |
984 | +#endif | |
985 | + } | |
986 | +} | |
987 | + | |
988 | +void xattrs_xattrs_get(struct tar_stat_info *st, char const *file_name, int fd) | |
989 | +{ | |
990 | + if (xattrs_option > 0) | |
991 | + { /* get all xattrs ... this include security.* and system.* if | |
992 | + available. We filter them here, but we have to filter them | |
993 | + in xattrs_xattrs_set() anyway. | |
994 | + */ | |
995 | + static ssize_t xsz = 1024; | |
996 | + static char *xatrs = NULL; | |
997 | + ssize_t xret = -1; | |
998 | + | |
999 | +#ifndef HAVE_XATTRS | |
1000 | + static int done = 0; | |
1001 | + if ((xattrs_option > 0) && !done) | |
1002 | + WARN ((0, 0, _("Xattr support requested, but not available"))); | |
1003 | + done = 1; | |
1004 | +#else | |
1005 | + | |
1006 | + if (!xatrs) xatrs = xmalloc (xsz); | |
9f0833cd MT |
1007 | + |
1008 | + while (((fd == -1) ? | |
1009 | + ((xret = llistxattr (file_name, xatrs, xsz)) == -1) : | |
547b54ef MT |
1010 | + ((xret = flistxattr (fd, xatrs, xsz)) == -1)) && |
1011 | + (errno == ERANGE)) | |
1012 | + { | |
1013 | + xsz <<= 1; | |
1014 | + xatrs = xrealloc (xatrs, xsz); | |
1015 | + } | |
1016 | + | |
1017 | + if (xret == -1) | |
9f0833cd | 1018 | + call_arg_warn ((fd == -1) ? "llistxattrs" : "flistxattrs", file_name); |
547b54ef MT |
1019 | + else |
1020 | + { | |
1021 | + const char *attr = xatrs; | |
1022 | + static ssize_t asz = 1024; | |
1023 | + static char *val = NULL; | |
9f0833cd | 1024 | + |
547b54ef | 1025 | + if (!val) val = xmalloc (asz); |
9f0833cd | 1026 | + |
547b54ef MT |
1027 | + while (xret > 0) |
1028 | + { | |
1029 | + size_t len = strlen (attr); | |
1030 | + ssize_t aret = 0; | |
9f0833cd MT |
1031 | + |
1032 | + /* Archive all xattrs during creation, decide at extraction time | |
1033 | + * which ones are of interest/use for the target filesystem. */ | |
1034 | + while (((fd == -1) ? | |
1035 | + ((aret = lgetxattr (file_name, attr, val, asz)) == -1) : | |
547b54ef MT |
1036 | + ((aret = fgetxattr (fd, attr, val, asz)) == -1)) && |
1037 | + (errno == ERANGE)) | |
1038 | + { | |
1039 | + asz <<= 1; | |
1040 | + val = xrealloc (val, asz); | |
1041 | + } | |
9f0833cd | 1042 | + |
547b54ef MT |
1043 | + if (aret != -1) |
1044 | + xheader_xattr_add (st, attr, val, aret); | |
1045 | + else if (errno != ENOATTR) | |
9f0833cd MT |
1046 | + call_arg_warn ((fd==-1) ? "lgetxattr" : "fgetxattr", file_name); |
1047 | + | |
547b54ef MT |
1048 | + attr += len + 1; |
1049 | + xret -= len + 1; | |
1050 | + } | |
1051 | + } | |
1052 | +#endif | |
1053 | + } | |
1054 | +} | |
1055 | + | |
1056 | +static void xattrs__fd_set(struct tar_stat_info const *st, | |
1057 | + char const *file_name, char typeflag, | |
1058 | + const char *attr, | |
1059 | + const char *ptr, size_t len) | |
1060 | +{ | |
1061 | +#ifdef HAVE_XATTRS | |
1062 | + if (ptr) | |
1063 | + { | |
1064 | + const char *sysname = "setxattr"; | |
1065 | + int ret = -1; | |
1066 | + | |
1067 | + if (typeflag != SYMTYPE) | |
1068 | + ret = setxattr (file_name, attr, ptr, len, 0); | |
1069 | + else | |
1070 | + { | |
1071 | + sysname = "lsetxattr"; | |
1072 | + ret = lsetxattr (file_name, attr, ptr, len, 0); | |
1073 | + } | |
1074 | + | |
1075 | + /* do not print warnings when SELinux is disabled */ | |
1076 | + if ((ret == -1) && (errno != EPERM) && (errno != ENOTSUP)) | |
1077 | + call_arg_error(sysname, file_name); | |
1078 | + } | |
1079 | +#endif | |
1080 | +} | |
1081 | + | |
1082 | +/* convert unix permissions into an ACL ... needed due to "default" ACLs */ | |
1083 | +#ifdef HAVE_LIBACL | |
1084 | +static acl_t perms2acl(int perms) | |
1085 | +{ | |
1086 | + char val[] = "user::---,group::---,other::---"; | |
1087 | + /* 0123456789 123456789 123456789 123456789 */ | |
1088 | + | |
1089 | + /* user */ | |
1090 | + if (perms & 0400) val[ 6] = 'r'; | |
1091 | + if (perms & 0200) val[ 7] = 'w'; | |
1092 | + if (perms & 0100) val[ 8] = 'x'; | |
1093 | + | |
1094 | + /* group */ | |
1095 | + if (perms & 0040) val[17] = 'r'; | |
1096 | + if (perms & 0020) val[18] = 'w'; | |
1097 | + if (perms & 0010) val[19] = 'x'; | |
1098 | + | |
1099 | + /* other */ | |
1100 | + if (perms & 0004) val[28] = 'r'; | |
1101 | + if (perms & 0002) val[29] = 'w'; | |
1102 | + if (perms & 0001) val[30] = 'x'; | |
9f0833cd | 1103 | + |
547b54ef MT |
1104 | + return (acl_from_text (val)); |
1105 | +} | |
1106 | +#endif | |
1107 | + | |
1108 | +static char *skip_to_ext_fields(char *ptr) | |
1109 | +{ | |
1110 | + ptr += strcspn(ptr, ":,\n"); /* skip tag name. Ie. user/group/default/mask */ | |
1111 | + | |
1112 | + if (*ptr != ':') | |
1113 | + return (ptr); /* error? no user/group field */ | |
1114 | + ++ptr; | |
9f0833cd | 1115 | + |
547b54ef MT |
1116 | + ptr += strcspn(ptr, ":,\n"); /* skip user/group name */ |
1117 | + | |
1118 | + if (*ptr != ':') | |
1119 | + return (ptr); /* error? no perms field */ | |
1120 | + ++ptr; | |
9f0833cd | 1121 | + |
547b54ef MT |
1122 | + ptr += strcspn(ptr, ":,\n"); /* skip perms */ |
1123 | + | |
1124 | + if (*ptr != ':') | |
1125 | + return (ptr); /* no extra fields */ | |
1126 | + | |
1127 | + return (ptr); | |
1128 | +} | |
1129 | + | |
1130 | +/* The POSIX draft allows extra fields after the three main ones. Star | |
1131 | + uses this to add a fourth field for user/group which is the numeric ID. | |
1132 | + We just skip all extra fields atm. */ | |
1133 | +static const char *fixup_extra_acl_fields(const char *ptr) | |
1134 | +{ | |
1135 | + char *src = (char *)ptr; | |
1136 | + char *dst = (char *)ptr; | |
1137 | + | |
1138 | + while (*src) | |
1139 | + { | |
1140 | + const char *old = src; | |
1141 | + size_t len = 0; | |
1142 | + | |
1143 | + src = skip_to_ext_fields(src); | |
1144 | + len = src - old; | |
1145 | + if (old != dst) memmove(dst, old, len); | |
1146 | + dst += len; | |
1147 | + | |
1148 | + if (*src == ':') /* We have extra fields, skip them all */ | |
1149 | + src += strcspn(src, "\n,"); | |
9f0833cd | 1150 | + |
547b54ef MT |
1151 | + if ((*src == '\n') || (*src == ',')) |
1152 | + *dst++ = *src++; /* also done when dst == src, but that's ok */ | |
1153 | + } | |
1154 | + if (src != dst) | |
1155 | + *dst = 0; | |
9f0833cd | 1156 | + |
547b54ef MT |
1157 | + return ptr; |
1158 | +} | |
1159 | + | |
1160 | +static void xattrs__acls_set(struct tar_stat_info const *st, | |
1161 | + char const *file_name, int type, | |
1162 | + const char *ptr, size_t len) | |
1163 | +{ /* "system.posix_acl_access" */ | |
1164 | +#ifdef HAVE_LIBACL | |
1165 | + acl_t acl; | |
1166 | + | |
1167 | + if (ptr) | |
1168 | + { | |
1169 | + /* assert (strlen (ptr) == len); */ | |
1170 | + ptr = fixup_extra_acl_fields(ptr); | |
9f0833cd | 1171 | + |
547b54ef MT |
1172 | + acl = acl_from_text (ptr); |
1173 | + acls_option = 1; | |
1174 | + } | |
1175 | + else if (acls_option > 0) | |
1176 | + acl = perms2acl (st->stat.st_mode); | |
1177 | + else | |
1178 | + return; /* don't call acl functions unless we first hit an ACL, or | |
1179 | + --acls was passed explicitly */ | |
9f0833cd | 1180 | + |
547b54ef MT |
1181 | + if (acl == (acl_t)NULL) |
1182 | + { | |
1183 | + call_arg_warn ("acl_from_text", file_name); | |
1184 | + return; | |
1185 | + } | |
9f0833cd | 1186 | + |
547b54ef MT |
1187 | + if (acl_set_file (file_name, type, acl) == -1) |
1188 | + { | |
1189 | + if (errno != ENOTSUP) | |
1190 | + call_arg_warn ("acl_set_file", file_name); | |
1191 | + } | |
1192 | + acl_free (acl); | |
1193 | +#endif | |
1194 | +} | |
1195 | + | |
1196 | +void xattrs_acls_set(struct tar_stat_info const *st, | |
1197 | + char const *file_name, char typeflag) | |
1198 | +{ | |
1199 | + if ((acls_option >= 0) && (typeflag != SYMTYPE)) | |
1200 | + { | |
1201 | +#ifndef HAVE_LIBACL | |
1202 | + static int done = 0; | |
1203 | + if (!done) | |
1204 | + WARN ((0, 0, _("ACL support requested, but not available"))); | |
1205 | + done = 1; | |
1206 | +#else | |
1207 | + xattrs__acls_set (st, file_name, ACL_TYPE_ACCESS, | |
1208 | + st->acls_a_ptr, st->acls_a_len); | |
9f0833cd | 1209 | + if ((typeflag == DIRTYPE) || (typeflag == GNUTYPE_DUMPDIR)) |
547b54ef MT |
1210 | + xattrs__acls_set (st, file_name, ACL_TYPE_DEFAULT, |
1211 | + st->acls_d_ptr, st->acls_d_len); | |
1212 | +#endif | |
1213 | + } | |
1214 | +} | |
1215 | + | |
1216 | +void xattrs_selinux_set(struct tar_stat_info const *st, | |
1217 | + char const *file_name, char typeflag) | |
1218 | +{ | |
1219 | + if ((selinux_context_option >= 0) && st->cntx_name) | |
1220 | + { | |
1221 | + const char *sysname = "setfilecon"; | |
1222 | + int ret = -1; | |
1223 | + | |
1224 | +#ifndef HAVE_LIBSELINUX | |
1225 | + static int done = 0; | |
1226 | + if (!done) | |
1227 | + WARN ((0, 0, _("SELinux support requested, but not available"))); | |
1228 | + done = 1; | |
1229 | +#else | |
1230 | + if (typeflag != SYMTYPE) | |
1231 | + ret = setfilecon (file_name, st->cntx_name); | |
1232 | + else | |
1233 | + { | |
1234 | + sysname = "lsetfilecon"; | |
1235 | + ret = lsetfilecon (file_name, st->cntx_name); | |
1236 | + } | |
1237 | + | |
1238 | + if ((ret == -1) && (errno == EPERM)) | |
1239 | + call_arg_warn(sysname, file_name); | |
1240 | + else if ((ret == -1) && (errno != EOPNOTSUPP)) | |
1241 | + call_arg_error(sysname, file_name); | |
1242 | +#endif | |
1243 | + } | |
1244 | +} | |
1245 | + | |
1246 | +void xattrs_xattrs_set(struct tar_stat_info const *st, | |
1247 | + char const *file_name, char typeflag) | |
1248 | +{ | |
1249 | + if ((xattrs_option >= 0) && st->xattr_map_size) | |
1250 | + { | |
1251 | + size_t scan = 0; | |
1252 | + | |
1253 | +#ifndef HAVE_XATTRS | |
1254 | + static int done = 0; | |
1255 | + if (!done) | |
1256 | + WARN ((0, 0, _("Xattr support requested, but not available"))); | |
1257 | + done = 1; | |
1258 | +#else | |
1259 | + while (scan < st->xattr_map_size) | |
1260 | + { | |
1261 | + char *keyword = st->xattr_map[scan].xkey; | |
1262 | + | |
1263 | + /* assert (!memcpy (keyword, "SCHILY.xattr.", strlen("SCHILY.xattr."))); */ | |
1264 | + keyword += strlen("SCHILY.xattr."); | |
1265 | + | |
1266 | + if (strncmp (keyword, "user.", strlen("user.")) && | |
9f0833cd | 1267 | + strncmp (keyword, "lustre.", strlen("lustre.")) && |
bd523de6 MT |
1268 | + strncmp (keyword, "trusted.", strlen("trusted.")) && |
1269 | + strncmp (keyword, "security.NTACL", strlen("security.NTACL"))) | |
547b54ef | 1270 | + continue; /* don't try and set anything but normal xattrs */ |
9f0833cd | 1271 | + |
547b54ef MT |
1272 | + xattrs__fd_set (st, file_name, typeflag, keyword, |
1273 | + st->xattr_map[scan].xval_ptr, | |
1274 | + st->xattr_map[scan].xval_len); | |
9f0833cd | 1275 | + |
547b54ef MT |
1276 | + ++scan; |
1277 | + } | |
1278 | +#endif | |
1279 | + } | |
1280 | +} | |
bd523de6 MT |
1281 | diff -urNp tar-1.24-orig/src/xattrs.h tar-1.24/src/xattrs.h |
1282 | --- tar-1.24-orig/src/xattrs.h 1970-01-01 01:00:00.000000000 +0100 | |
1283 | +++ tar-1.24/src/xattrs.h 2010-10-25 10:24:52.569214526 +0200 | |
547b54ef MT |
1284 | @@ -0,0 +1,14 @@ |
1285 | + | |
1286 | +extern void xattrs_acls_get(struct tar_stat_info *st, | |
1287 | + char const *file_name, int fd, int xisfile); | |
1288 | +extern void xattrs_selinux_get(struct tar_stat_info *st, | |
1289 | + char const *file_name, int fd); | |
1290 | +extern void xattrs_xattrs_get(struct tar_stat_info *st, | |
1291 | + char const *file_name, int fd); | |
1292 | + | |
1293 | +extern void xattrs_acls_set(struct tar_stat_info const *st, | |
1294 | + char const *file_name, char typeflag); | |
1295 | +extern void xattrs_selinux_set(struct tar_stat_info const *st, | |
1296 | + char const *file_name, char typeflag); | |
1297 | +extern void xattrs_xattrs_set(struct tar_stat_info const *st, | |
1298 | + char const *file_name, char typeflag); | |
bd523de6 MT |
1299 | diff -urNp tar-1.24-orig/src/xheader.c tar-1.24/src/xheader.c |
1300 | --- tar-1.24-orig/src/xheader.c 2010-10-24 20:07:46.000000000 +0200 | |
1301 | +++ tar-1.24/src/xheader.c 2010-10-25 10:24:52.570223396 +0200 | |
1302 | @@ -460,6 +460,74 @@ xheader_write_global (struct xheader *xh | |
9f0833cd MT |
1303 | } |
1304 | } | |
1305 | ||
1306 | +void xheader_xattr_init(struct tar_stat_info *st) | |
1307 | +{ | |
1308 | + st->xattr_map = NULL; | |
1309 | + st->xattr_map_size = 0; | |
1310 | +} | |
1311 | + | |
1312 | +void xheader_xattr_free(struct xattr_array *xattr_map, size_t xattr_map_size) | |
1313 | +{ | |
1314 | + size_t scan = 0; | |
1315 | + | |
1316 | + while (scan < xattr_map_size) | |
1317 | + { | |
1318 | + free (xattr_map[scan].xkey); | |
1319 | + free (xattr_map[scan].xval_ptr); | |
1320 | + | |
1321 | + ++scan; | |
1322 | + } | |
1323 | + free (xattr_map); | |
1324 | +} | |
1325 | + | |
1326 | +static void xheader_xattr__add(struct xattr_array **xattr_map, | |
1327 | + size_t *xattr_map_size, | |
1328 | + const char *key, const char *val, size_t len) | |
1329 | +{ | |
1330 | + size_t pos = (*xattr_map_size)++; | |
1331 | + | |
1332 | + *xattr_map = xrealloc (*xattr_map, | |
1333 | + *xattr_map_size * sizeof(struct xattr_array)); | |
1334 | + (*xattr_map)[pos].xkey = xstrdup (key); | |
1335 | + (*xattr_map)[pos].xval_ptr = xmemdup (val, len + 1); | |
1336 | + (*xattr_map)[pos].xval_len = len; | |
1337 | +} | |
1338 | + | |
1339 | +void xheader_xattr_add(struct tar_stat_info *st, | |
1340 | + const char *key, const char *val, size_t len) | |
1341 | +{ | |
1342 | + size_t klen = strlen (key); | |
1343 | + char *xkey = xmalloc (strlen("SCHILY.xattr.") + klen + 1); | |
1344 | + char *tmp = xkey; | |
1345 | + | |
1346 | + tmp = stpcpy (tmp, "SCHILY.xattr."); | |
1347 | + tmp = stpcpy (tmp, key); | |
1348 | + | |
1349 | + xheader_xattr__add (&st->xattr_map, &st->xattr_map_size, xkey, val, len); | |
1350 | + | |
1351 | + free (xkey); | |
1352 | +} | |
1353 | + | |
1354 | +void xheader_xattr_copy(const struct tar_stat_info *st, | |
1355 | + struct xattr_array **xattr_map, size_t *xattr_map_size) | |
1356 | +{ | |
1357 | + size_t scan = 0; | |
1358 | + | |
1359 | + *xattr_map = NULL; | |
1360 | + *xattr_map_size = 0; | |
1361 | + | |
1362 | + while (scan < st->xattr_map_size) | |
1363 | + { | |
1364 | + char *key = st->xattr_map[scan].xkey; | |
1365 | + char *val = st->xattr_map[scan].xval_ptr; | |
1366 | + size_t len = st->xattr_map[scan].xval_len; | |
1367 | + | |
1368 | + xheader_xattr__add(xattr_map, xattr_map_size, key, val, len); | |
1369 | + | |
1370 | + ++scan; | |
1371 | + } | |
1372 | +} | |
1373 | + | |
1374 | \f | |
1375 | /* General Interface */ | |
1376 | ||
bd523de6 | 1377 | @@ -473,6 +541,7 @@ struct xhdr_tab |
9f0833cd MT |
1378 | struct xheader *, void const *data); |
1379 | void (*decoder) (struct tar_stat_info *, char const *, char const *, size_t); | |
1380 | int flags; | |
1381 | + bool prefix; | |
1382 | }; | |
1383 | ||
1384 | /* This declaration must be extern, because ISO C99 section 6.9.2 | |
bd523de6 | 1385 | @@ -489,8 +558,17 @@ locate_handler (char const *keyword) |
9f0833cd MT |
1386 | struct xhdr_tab const *p; |
1387 | ||
1388 | for (p = xhdr_tab; p->keyword; p++) | |
1389 | - if (strcmp (p->keyword, keyword) == 0) | |
1390 | - return p; | |
1391 | + if (p->prefix) | |
1392 | + { | |
1393 | + if (strncmp (p->keyword, keyword, strlen(p->keyword)) == 0) | |
1394 | + return p; | |
1395 | + } | |
1396 | + else | |
1397 | + { | |
1398 | + if (strcmp (p->keyword, keyword) == 0) | |
1399 | + return p; | |
1400 | + } | |
1401 | + | |
1402 | return NULL; | |
1403 | } | |
1404 | ||
bd523de6 | 1405 | @@ -500,7 +578,7 @@ xheader_protected_pattern_p (const char |
9f0833cd MT |
1406 | struct xhdr_tab const *p; |
1407 | ||
1408 | for (p = xhdr_tab; p->keyword; p++) | |
1409 | - if ((p->flags & XHDR_PROTECTED) && fnmatch (pattern, p->keyword, 0) == 0) | |
1410 | + if (!p->prefix && (p->flags & XHDR_PROTECTED) && fnmatch (pattern, p->keyword, 0) == 0) | |
1411 | return true; | |
1412 | return false; | |
1413 | } | |
bd523de6 | 1414 | @@ -511,7 +589,7 @@ xheader_protected_keyword_p (const char |
9f0833cd MT |
1415 | struct xhdr_tab const *p; |
1416 | ||
1417 | for (p = xhdr_tab; p->keyword; p++) | |
1418 | - if ((p->flags & XHDR_PROTECTED) && strcmp (p->keyword, keyword) == 0) | |
1419 | + if (!p->prefix && (p->flags & XHDR_PROTECTED) && strcmp (p->keyword, keyword) == 0) | |
1420 | return true; | |
1421 | return false; | |
1422 | } | |
bd523de6 | 1423 | @@ -1470,6 +1548,71 @@ volume_filename_decoder (struct tar_stat |
9f0833cd MT |
1424 | } |
1425 | ||
1426 | static void | |
1427 | +xattr_selinux_coder (struct tar_stat_info const *st, char const *keyword, | |
1428 | + struct xheader *xhdr, void const *data) | |
1429 | +{ | |
1430 | + code_string (st->cntx_name, keyword, xhdr); | |
1431 | +} | |
1432 | + | |
1433 | +static void | |
1434 | +xattr_selinux_decoder (struct tar_stat_info *st, | |
1435 | + char const *keyword, char const *arg, size_t size) | |
1436 | +{ | |
1437 | + decode_string (&st->cntx_name, arg); | |
1438 | +} | |
1439 | + | |
1440 | +static void | |
1441 | +xattr_acls_a_coder (struct tar_stat_info const *st , char const *keyword, | |
1442 | + struct xheader *xhdr, void const *data) | |
1443 | +{ | |
1444 | + xheader_print_n (xhdr, keyword, st->acls_a_ptr, st->acls_a_len); | |
1445 | +} | |
1446 | + | |
1447 | +static void | |
1448 | +xattr_acls_a_decoder (struct tar_stat_info *st, | |
1449 | + char const *keyword, char const *arg, size_t size) | |
1450 | +{ | |
1451 | + st->acls_a_ptr = xmemdup (arg, size + 1); | |
1452 | + st->acls_a_len = size; | |
1453 | +} | |
1454 | + | |
1455 | +static void | |
1456 | +xattr_acls_d_coder (struct tar_stat_info const *st , char const *keyword, | |
1457 | + struct xheader *xhdr, void const *data) | |
1458 | +{ | |
1459 | + xheader_print_n (xhdr, keyword, st->acls_d_ptr, st->acls_d_len); | |
1460 | +} | |
1461 | + | |
1462 | +static void | |
1463 | +xattr_acls_d_decoder (struct tar_stat_info *st, | |
1464 | + char const *keyword, char const *arg, size_t size) | |
1465 | +{ | |
1466 | + st->acls_d_ptr = xmemdup (arg, size + 1); | |
1467 | + st->acls_d_len = size; | |
1468 | +} | |
1469 | + | |
1470 | +static void | |
1471 | +xattr_coder (struct tar_stat_info const *st , char const *keyword, | |
1472 | + struct xheader *xhdr, void const *data) | |
1473 | +{ | |
1474 | + struct xattr_array *xattr_map = st->xattr_map; | |
1475 | + const size_t *off = data; | |
1476 | + xheader_print_n (xhdr, keyword, | |
1477 | + xattr_map[*off].xval_ptr, xattr_map[*off].xval_len); | |
1478 | +} | |
1479 | + | |
1480 | +static void | |
1481 | +xattr_decoder (struct tar_stat_info *st, | |
1482 | + char const *keyword, char const *arg, size_t size) | |
1483 | +{ | |
1484 | + char *xstr = NULL; | |
1485 | + | |
1486 | + xstr = xmemdup(arg, size + 1); | |
1487 | + xheader_xattr_add(st, keyword + strlen("SCHILY.xattr."), xstr, size); | |
1488 | + free(xstr); | |
1489 | +} | |
1490 | + | |
1491 | +static void | |
1492 | sparse_major_coder (struct tar_stat_info const *st, char const *keyword, | |
1493 | struct xheader *xhdr, void const *data) | |
1494 | { | |
bd523de6 | 1495 | @@ -1506,53 +1649,53 @@ sparse_minor_decoder (struct tar_stat_in |
9f0833cd MT |
1496 | } |
1497 | ||
1498 | struct xhdr_tab const xhdr_tab[] = { | |
1499 | - { "atime", atime_coder, atime_decoder, 0 }, | |
1500 | - { "comment", dummy_coder, dummy_decoder, 0 }, | |
1501 | - { "charset", dummy_coder, dummy_decoder, 0 }, | |
1502 | - { "ctime", ctime_coder, ctime_decoder, 0 }, | |
1503 | - { "gid", gid_coder, gid_decoder, 0 }, | |
1504 | - { "gname", gname_coder, gname_decoder, 0 }, | |
1505 | - { "linkpath", linkpath_coder, linkpath_decoder, 0 }, | |
1506 | - { "mtime", mtime_coder, mtime_decoder, 0 }, | |
1507 | - { "path", path_coder, path_decoder, 0 }, | |
1508 | - { "size", size_coder, size_decoder, 0 }, | |
1509 | - { "uid", uid_coder, uid_decoder, 0 }, | |
1510 | - { "uname", uname_coder, uname_decoder, 0 }, | |
1511 | + { "atime", atime_coder, atime_decoder, 0, false }, | |
1512 | + { "comment", dummy_coder, dummy_decoder, 0, false }, | |
1513 | + { "charset", dummy_coder, dummy_decoder, 0, false }, | |
1514 | + { "ctime", ctime_coder, ctime_decoder, 0, false }, | |
1515 | + { "gid", gid_coder, gid_decoder, 0, false }, | |
1516 | + { "gname", gname_coder, gname_decoder, 0, false }, | |
1517 | + { "linkpath", linkpath_coder, linkpath_decoder, 0, false }, | |
1518 | + { "mtime", mtime_coder, mtime_decoder, 0, false }, | |
1519 | + { "path", path_coder, path_decoder, 0, false }, | |
1520 | + { "size", size_coder, size_decoder, 0, false }, | |
1521 | + { "uid", uid_coder, uid_decoder, 0, false }, | |
1522 | + { "uname", uname_coder, uname_decoder, 0, false }, | |
1523 | ||
1524 | /* Sparse file handling */ | |
1525 | { "GNU.sparse.name", path_coder, path_decoder, | |
1526 | - XHDR_PROTECTED }, | |
1527 | + XHDR_PROTECTED, false }, | |
1528 | { "GNU.sparse.major", sparse_major_coder, sparse_major_decoder, | |
1529 | - XHDR_PROTECTED }, | |
1530 | + XHDR_PROTECTED, false }, | |
1531 | { "GNU.sparse.minor", sparse_minor_coder, sparse_minor_decoder, | |
1532 | - XHDR_PROTECTED }, | |
1533 | + XHDR_PROTECTED, false }, | |
1534 | { "GNU.sparse.realsize", sparse_size_coder, sparse_size_decoder, | |
1535 | - XHDR_PROTECTED }, | |
1536 | + XHDR_PROTECTED, false }, | |
1537 | { "GNU.sparse.numblocks", sparse_numblocks_coder, sparse_numblocks_decoder, | |
1538 | - XHDR_PROTECTED }, | |
1539 | + XHDR_PROTECTED, false }, | |
1540 | ||
1541 | /* tar 1.14 - 1.15.90 keywords. */ | |
1542 | { "GNU.sparse.size", sparse_size_coder, sparse_size_decoder, | |
1543 | - XHDR_PROTECTED }, | |
1544 | + XHDR_PROTECTED, false }, | |
1545 | /* tar 1.14 - 1.15.1 keywords. Multiple instances of these appeared in 'x' | |
1546 | headers, and each of them was meaningful. It confilcted with POSIX specs, | |
1547 | which requires that "when extended header records conflict, the last one | |
1548 | given in the header shall take precedence." */ | |
1549 | { "GNU.sparse.offset", sparse_offset_coder, sparse_offset_decoder, | |
1550 | - XHDR_PROTECTED }, | |
1551 | + XHDR_PROTECTED, false }, | |
1552 | { "GNU.sparse.numbytes", sparse_numbytes_coder, sparse_numbytes_decoder, | |
1553 | - XHDR_PROTECTED }, | |
1554 | + XHDR_PROTECTED, false }, | |
1555 | /* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */ | |
1556 | { "GNU.sparse.map", NULL /* Unused, see pax_dump_header() */, | |
1557 | - sparse_map_decoder, 0 }, | |
1558 | + sparse_map_decoder, 0, false }, | |
1559 | ||
1560 | { "GNU.dumpdir", dumpdir_coder, dumpdir_decoder, | |
1561 | - XHDR_PROTECTED }, | |
1562 | + XHDR_PROTECTED, false }, | |
1563 | ||
1564 | /* Keeps the tape/volume label. May be present only in the global headers. | |
1565 | Equivalent to GNUTYPE_VOLHDR. */ | |
1566 | { "GNU.volume.label", volume_label_coder, volume_label_decoder, | |
1567 | - XHDR_PROTECTED | XHDR_GLOBAL }, | |
1568 | + XHDR_PROTECTED | XHDR_GLOBAL, false }, | |
1569 | ||
1570 | /* These may be present in a first global header of the archive. | |
1571 | They provide the same functionality as GNUTYPE_MULTIVOL header. | |
bd523de6 | 1572 | @@ -1561,11 +1704,41 @@ struct xhdr_tab const xhdr_tab[] = { |
9f0833cd MT |
1573 | GNU.volume.offset keeps the offset of the start of this volume, |
1574 | otherwise kept in oldgnu_header.offset. */ | |
1575 | { "GNU.volume.filename", volume_label_coder, volume_filename_decoder, | |
1576 | - XHDR_PROTECTED | XHDR_GLOBAL }, | |
1577 | + XHDR_PROTECTED | XHDR_GLOBAL, false }, | |
1578 | { "GNU.volume.size", volume_size_coder, volume_size_decoder, | |
1579 | - XHDR_PROTECTED | XHDR_GLOBAL }, | |
1580 | + XHDR_PROTECTED | XHDR_GLOBAL, false }, | |
1581 | { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder, | |
1582 | - XHDR_PROTECTED | XHDR_GLOBAL }, | |
1583 | + XHDR_PROTECTED | XHDR_GLOBAL, false }, | |
1584 | + | |
1585 | + /* We get the SELinux value from filecon, so add a namespace for SELinux | |
1586 | + instead of storing it in SCHILY.xattr.* (which would be RAW). */ | |
1587 | + { "RHT.security.selinux", | |
1588 | + xattr_selinux_coder, xattr_selinux_decoder, 0, false }, | |
1589 | + | |
1590 | + /* ACLs, use the star format... */ | |
1591 | + { "SCHILY.acl.access", | |
1592 | + xattr_acls_a_coder, xattr_acls_a_decoder, 0, false }, | |
1593 | + | |
1594 | + { "SCHILY.acl.default", | |
1595 | + xattr_acls_d_coder, xattr_acls_d_decoder, 0, false }, | |
1596 | + | |
1597 | + /* FIXME: These are compat. for FC-6 ... we shipped a tar using the generic | |
1598 | + header names by accident. */ | |
1599 | + { "SCHILY.xattr.security.selinux", | |
1600 | + xattr_selinux_coder, xattr_selinux_decoder, 0, false }, | |
1601 | + { "SCHILY.xattr.system.posix_acl_access", | |
1602 | + xattr_acls_a_coder, xattr_acls_a_decoder, 0, false }, | |
1603 | + { "SCHILY.xattr.system.posix_acl_default", | |
1604 | + xattr_acls_d_coder, xattr_acls_d_decoder, 0, false }, | |
1605 | + | |
1606 | + /* xattrs use the star format. note we only save some variants... */ | |
1607 | + { "SCHILY.xattr.user", xattr_coder, xattr_decoder, 0, true }, | |
1608 | + { "SCHILY.xattr.trusted", xattr_coder, xattr_decoder, 0, true }, | |
1609 | + { "SCHILY.xattr.lustre", xattr_coder, xattr_decoder, 0, true }, | |
bd523de6 | 1610 | + { "SCHILY.xattr.security.NTACL", xattr_coder, xattr_decoder, 0, true }, |
9f0833cd MT |
1611 | + |
1612 | + /* ignore everything else in the xattr namespaces... */ | |
1613 | + { "SCHILY.xattr", dummy_coder, dummy_decoder, 0, true }, | |
1614 | ||
1615 | - { NULL, NULL, NULL, 0 } | |
1616 | + { NULL, NULL, NULL, 0, false } | |
1617 | }; |