]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/xattr.c
Some small fixes to the counting and some small relayout of small code sniplets.
[bacula/bacula] / bacula / src / filed / xattr.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2008-2009 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  * Functions to handle Extended Attributes for bacula.
30  *
31  * Extended Attributes are so OS specific we only restore Extended Attributes if
32  * they were saved using a filed on the same platform.
33  *
34  * Currently we support the following OSes:
35  *   - FreeBSD (Extended Attributes)
36  *   - Darwin (Extended Attributes)
37  *   - Linux (Extended Attributes)
38  *   - NetBSD (Extended Attributes)
39  *   - Solaris (Extended Attributes and Extensible Attributes)
40  *
41  *   Written by Marco van Wieringen, November MMVIII
42  *
43  *   Version $Id$
44  */
45
46 #include "bacula.h"
47 #include "filed.h"
48
49 #if !defined(HAVE_XATTR)
50 /*
51  * Entry points when compiled without support for XATTRs or on an unsupported platform.
52  */
53 bxattr_exit_code build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
54 {
55    return bxattr_exit_fatal;
56 }
57
58 bxattr_exit_code parse_xattr_streams(JCR *jcr, int stream)
59 {
60    return bxattr_exit_fatal;
61 }
62 #else
63 /*
64  * Send a XATTR stream to the SD.
65  */
66 static bxattr_exit_code send_xattr_stream(JCR *jcr, int stream)
67 {
68    BSOCK *sd = jcr->store_bsock;
69    POOLMEM *msgsave;
70 #ifdef FD_NO_SEND_TEST
71    return bxattr_exit_ok;
72 #endif
73
74    /*
75     * Sanity check
76     */
77    if (jcr->xattr_data->content_length <= 0) {
78       return bxattr_exit_ok;
79    }
80
81    /*
82     * Send header
83     */
84    if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) {
85       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
86             sd->bstrerror());
87       return bxattr_exit_fatal;
88    }
89
90    /*
91     * Send the buffer to the storage deamon
92     */
93    Dmsg1(400, "Backing up XATTR <%s>\n", jcr->xattr_data->content);
94    msgsave = sd->msg;
95    sd->msg = jcr->xattr_data->content;
96    sd->msglen = jcr->xattr_data->content_length;
97    if (!sd->send()) {
98       sd->msg = msgsave;
99       sd->msglen = 0;
100       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
101             sd->bstrerror());
102       return bxattr_exit_fatal;
103    }
104
105    jcr->JobBytes += sd->msglen;
106    sd->msg = msgsave;
107    if (!sd->signal(BNET_EOD)) {
108       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
109             sd->bstrerror());
110       return bxattr_exit_fatal;
111    }
112    Dmsg1(200, "XATTR of file: %s successfully backed up!\n", jcr->last_fname);
113    return bxattr_exit_ok;
114 }
115
116 /*
117  * This is a supported OS, See what kind of interface we should use.
118  * Start with the generic interface used by most OS-es.
119  */
120 #if defined(HAVE_DARWIN_OS) || \
121     defined(HAVE_FREEBSD_OS) || \
122     defined(HAVE_LINUX_OS) || \
123     defined(HAVE_NETBSD_OS)
124        
125 #ifdef HAVE_SYS_XATTR_H
126 #include <sys/xattr.h>
127 #endif
128
129 /*
130  * Define the supported XATTR streams for this OS
131  */
132 #if defined(HAVE_DARWIN_OS)
133 static int os_default_xattr_streams[1] = { STREAM_XATTR_DARWIN };
134 #elif defined(HAVE_FREEBSD_OS)
135 static int os_default_xattr_streams[1] = { STREAM_XATTR_FREEBSD };
136 #elif defined(HAVE_LINUX_OS)
137 static int os_default_xattr_streams[1] = { STREAM_XATTR_LINUX };
138 #elif defined(HAVE_NETBSD_OS)
139 static int os_default_xattr_streams[1] = { STREAM_XATTR_NETBSD };
140 #endif
141
142 /*
143  * OSX doesn't have llistxattr, lgetxattr and lsetxattr but has
144  * listxattr, getxattr and setxattr with an extra options argument
145  * which mimics the l variants of the functions when we specify
146  * XATTR_NOFOLLOW as the options value.
147  */
148 #if defined(HAVE_DARWIN_OS)
149    #define llistxattr(path, list, size) listxattr((path), (list), (size), XATTR_NOFOLLOW)
150    #define lgetxattr(path, name, value, size) getxattr((path), (name), (value), (size), 0, XATTR_NOFOLLOW)
151    #define lsetxattr(path, name, value, size, flags) setxattr((path), (name), (value), (size), (flags), XATTR_NOFOLLOW)
152 #else
153    /*
154     * Fallback to the non l-functions when those are not available.
155     */
156    #if defined(HAVE_GETXATTR) && !defined(HAVE_LGETXATTR)
157    #define lgetxattr getxattr
158    #endif
159    #if defined(HAVE_SETXATTR) && !defined(HAVE_LSETXATTR)
160    #define lsetxattr setxattr
161    #endif
162    #if defined(HAVE_LISTXATTR) && !defined(HAVE_LLISTXATTR)
163    #define llistxattr listxattr
164    #endif
165 #endif
166
167 static void xattr_drop_internal_table(xattr_t *xattr_value_list)
168 {
169    xattr_t *current_xattr;
170
171    /*
172     * Walk the list of xattrs and free allocated memory on traversing.
173     */
174    for (current_xattr = xattr_value_list;
175         current_xattr != (xattr_t *)NULL;
176         current_xattr++) {
177       /*
178        * See if we can shortcut.
179        */
180       if (current_xattr->magic != XATTR_MAGIC)
181          break;
182
183       free(current_xattr->name);
184
185       if (current_xattr->value_length > 0)
186          free(current_xattr->value);
187    }
188
189    /*
190     * Free the array of control structs.
191     */
192    free(xattr_value_list);
193 }
194
195 /*
196  * The xattr stream for OSX, FreeBSD, Linux and NetBSD is a serialized stream of bytes
197  * which encodes one or more xattr_t structures.
198  *
199  * The Serialized stream consists of the following elements:
200  *    magic - A magic string which makes it easy to detect any binary incompatabilites
201  *    name_length - The length of the following xattr name
202  *    name - The name of the extended attribute
203  *    value_length - The length of the following xattr data
204  *    value - The actual content of the extended attribute
205  *
206  * This is repeated 1 or more times.
207  * 
208  */
209 static uint32_t serialize_xattr_stream(JCR *jcr, uint32_t expected_serialize_len, xattr_t *xattr_value_list)
210 {
211    xattr_t *current_xattr;
212    ser_declare;
213
214    /*
215     * Make sure the serialized stream fits in the poolmem buffer.
216     * We allocate some more to be sure the stream is gonna fit.
217     */
218    jcr->xattr_data->content = check_pool_memory_size(jcr->xattr_data->content, expected_serialize_len + 10);
219    ser_begin(jcr->xattr_data->content, expected_serialize_len + 10);
220
221    /*
222     * Walk the list of xattrs and serialize the data.
223     */
224    for (current_xattr = xattr_value_list; current_xattr != (xattr_t *)NULL; current_xattr++) {
225       /*
226        * See if we can shortcut.
227        */
228       if (current_xattr->magic != XATTR_MAGIC)
229          break;
230
231       ser_uint32(current_xattr->magic);
232       ser_uint32(current_xattr->name_length);
233       ser_bytes(current_xattr->name, current_xattr->name_length);
234
235       ser_uint32(current_xattr->value_length);
236       ser_bytes(current_xattr->value, current_xattr->value_length);
237    }
238
239    ser_end(jcr->xattr_data->content, expected_serialize_len + 10);
240    jcr->xattr_data->content_length = ser_length(jcr->xattr_data->content);
241    return jcr->xattr_data->content_length;
242 }
243
244 static bxattr_exit_code generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt)
245 {
246    int count = 0;
247    int32_t xattr_list_len,
248            xattr_value_len;
249    uint32_t expected_serialize_len = 0;
250    char *xattr_list, *bp;
251    xattr_t *xattr_value_list = NULL, *current_xattr;
252    bxattr_exit_code retval = bxattr_exit_error;
253    berrno be;
254
255    /*
256     * First get the length of the available list with extended attributes.
257     */
258    xattr_list_len = llistxattr(jcr->last_fname, NULL, 0);
259    if (xattr_list_len < 0) {
260       switch (errno) {
261       case ENOENT:
262          return bxattr_exit_ok;
263       default:
264          Mmsg2(jcr->errmsg, _("llistxattr error on file \"%s\": ERR=%s\n"),
265                jcr->last_fname, be.bstrerror());
266          Dmsg2(100, "llistxattr error file=%s ERR=%s\n",
267                jcr->last_fname, be.bstrerror());
268          return bxattr_exit_error;
269       }
270    } else if (xattr_list_len == 0) {
271       return bxattr_exit_ok;
272    }
273
274    /*
275     * Allocate room for the extented attribute list.
276     */
277    xattr_list = (char *)malloc(xattr_list_len + 1);
278    memset((caddr_t)xattr_list, 0, xattr_list_len + 1);
279
280    /*
281     * Get the actual list of extended attributes names for a file.
282     */
283    xattr_list_len = llistxattr(jcr->last_fname, xattr_list, xattr_list_len);
284    if (xattr_list_len < 0) {
285       switch (errno) {
286       case ENOENT:
287          retval = bxattr_exit_ok;
288          goto bail_out;
289       default:
290          Mmsg2(jcr->errmsg, _("llistxattr error on file \"%s\": ERR=%s\n"),
291                jcr->last_fname, be.bstrerror());
292          Dmsg2(100, "llistxattr error file=%s ERR=%s\n",
293                jcr->last_fname, be.bstrerror());
294          goto bail_out;
295       }
296    }
297    xattr_list[xattr_list_len] = '\0';
298
299    /*
300     * Count the number of extended attributes on a file.
301     */
302    bp = xattr_list;
303    while ((bp - xattr_list) + 1 < xattr_list_len) {
304 #if defined(HAVE_LINUX_OS)
305       /*
306        * On Linux you also get the acls in the extented attribute list.
307        * So we check if we are already backing up acls and if we do we
308        * don't store the extended attribute with the same info.
309        */
310       if ((ff_pkt->flags & FO_ACL) == 0 || strcmp(bp, "system.posix_acl_access"))
311          count++;
312 #else
313       count++;
314 #endif
315
316       bp = strchr(bp, '\0') + 1;
317    }
318
319    if (count == 0) {
320       retval = bxattr_exit_ok;
321       goto bail_out;
322    }
323
324    /*
325     * Allocate enough room to hold all extended attributes.
326     * After allocating the storage make sure its empty by zeroing it.
327     */
328    xattr_value_list = (xattr_t *)malloc(count * sizeof(xattr_t));
329    memset((caddr_t)xattr_value_list, 0, count * sizeof(xattr_t));
330
331    /*
332     * Walk the list of extended attributes names and retrieve the data.
333     * We already count the bytes needed for serializing the stream later on.
334     */
335    current_xattr = xattr_value_list;
336    bp = xattr_list;
337    while ((bp - xattr_list) + 1 < xattr_list_len) {
338 #if defined(HAVE_LINUX_OS)
339       /*
340        * On Linux you also get the acls in the extented attribute list.
341        * So we check if we are already backing up acls and if we do we
342        * don't store the extended attribute with the same info.
343        */
344       if (ff_pkt->flags & FO_ACL && !strcmp(bp, "system.posix_acl_access")) {
345          bp = strchr(bp, '\0') + 1;
346          continue;
347       }
348 #endif
349
350       /*
351        * Each xattr valuepair starts with a magic so we can parse it easier.
352        */
353       current_xattr->magic = XATTR_MAGIC;
354       expected_serialize_len += sizeof(current_xattr->magic);
355
356       /*
357        * Allocate space for storing the name.
358        */
359       current_xattr->name_length = strlen(bp);
360       current_xattr->name = (char *)malloc(current_xattr->name_length);
361       memcpy((caddr_t)current_xattr->name, (caddr_t)bp, current_xattr->name_length);
362
363       expected_serialize_len += sizeof(current_xattr->name_length) + current_xattr->name_length;
364
365       /*
366        * First see how long the value is for the extended attribute.
367        */
368       xattr_value_len = lgetxattr(jcr->last_fname, bp, NULL, 0);
369       if (xattr_value_len < 0) {
370          switch (errno) {
371          case ENOENT:
372             retval = bxattr_exit_ok;
373             goto bail_out;
374          default:
375             Mmsg2(jcr->errmsg, _("lgetxattr error on file \"%s\": ERR=%s\n"),
376                   jcr->last_fname, be.bstrerror());
377             Dmsg2(100, "lgetxattr error file=%s ERR=%s\n",
378                   jcr->last_fname, be.bstrerror());
379             goto bail_out;
380          }
381       }
382
383       /*
384        * Allocate space for storing the value.
385        */
386       current_xattr->value = (char *)malloc(xattr_value_len);
387       memset((caddr_t)current_xattr->value, 0, xattr_value_len);
388
389       xattr_value_len = lgetxattr(jcr->last_fname, bp, current_xattr->value, xattr_value_len);
390       if (xattr_value_len < 0) {
391          switch (errno) {
392          case ENOENT:
393             retval = bxattr_exit_ok;
394             goto bail_out;
395          default:
396             Mmsg2(jcr->errmsg, _("lgetxattr error on file \"%s\": ERR=%s\n"),
397                   jcr->last_fname, be.bstrerror());
398             Dmsg2(100, "lgetxattr error file=%s ERR=%s\n",
399                   jcr->last_fname, be.bstrerror());
400             goto bail_out;
401          }
402       }
403
404       /*
405        * Store the actual length of the value.
406        */
407       current_xattr->value_length = xattr_value_len;
408       expected_serialize_len += sizeof(current_xattr->value_length) + current_xattr->value_length;
409
410       /*
411        * Protect ourself against things getting out of hand.
412        */
413       if (expected_serialize_len >= MAX_XATTR_STREAM) {
414          Mmsg2(jcr->errmsg, _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"),
415                jcr->last_fname, MAX_XATTR_STREAM);
416          goto bail_out;
417       }
418       
419       /*
420        * Next attribute.
421        */
422       current_xattr++;
423       bp = strchr(bp, '\0') + 1;
424    }
425
426    /*
427     * Serialize the datastream.
428     */
429    if (serialize_xattr_stream(jcr, expected_serialize_len, xattr_value_list) < expected_serialize_len) {
430       Mmsg1(jcr->errmsg, _("Failed to serialize extended attributes on file \"%s\"\n"),
431             jcr->last_fname);
432       Dmsg1(100, "Failed to serialize extended attributes on file \"%s\"\n",
433             jcr->last_fname);
434       goto bail_out;
435    }
436
437    xattr_drop_internal_table(xattr_value_list);
438    free(xattr_list);
439
440    /*
441     * Send the datastream to the SD.
442     */
443    return send_xattr_stream(jcr, os_default_xattr_streams[0]);
444
445 bail_out:
446    if (xattr_value_list) {
447       xattr_drop_internal_table(xattr_value_list);
448    }
449    free(xattr_list);
450    return retval;
451 }
452
453 static bxattr_exit_code generic_xattr_parse_streams(JCR *jcr, int stream)
454 {
455    unser_declare;
456    xattr_t current_xattr;
457    bxattr_exit_code retval = bxattr_exit_ok;
458    berrno be;
459
460    /*
461     * Parse the stream and perform the setxattr calls on the file.
462     *
463     * Start unserializing the data. We keep on looping while we have not
464     * unserialized all bytes in the stream.
465     */
466    unser_begin(jcr->xattr_data->content, jcr->xattr_data->content_length);
467    while (unser_length(jcr->xattr_data->content) < jcr->xattr_data->content_length) {
468       /*
469        * First make sure the magic is present. This way we can easily catch corruption.
470        * Any missing MAGIC is fatal we do NOT try to continue.
471        */
472       unser_uint32(current_xattr.magic);
473       if (current_xattr.magic != XATTR_MAGIC) {
474          Mmsg1(jcr->errmsg, _("Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n"),
475                jcr->last_fname);
476          Dmsg1(100, "Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n",
477                jcr->last_fname);
478          return bxattr_exit_error;
479       }
480
481       /*
482        * Decode the valuepair. First decode the length of the name.
483        */
484       unser_uint32(current_xattr.name_length);
485       
486       /*
487        * Allocate room for the name and decode its content.
488        */
489       current_xattr.name = (char *)malloc(current_xattr.name_length + 1);
490       unser_bytes(current_xattr.name, current_xattr.name_length);
491
492       /*
493        * The xattr_name needs to be null terminated for lsetxattr.
494        */
495       current_xattr.name[current_xattr.name_length] = '\0';
496
497       /*
498        * Decode the value length.
499        */
500       unser_uint32(current_xattr.value_length);
501
502       /*
503        * Allocate room for the value and decode its content.
504        */
505       current_xattr.value = (char *)malloc(current_xattr.value_length);
506       unser_bytes(current_xattr.value, current_xattr.value_length);
507
508       /*
509        * Try to set the extended attribute on the file.
510        * If we fail to set this attribute we flag the error but its not fatal,
511        * we try to restore the other extended attributes too.
512        */
513       if (lsetxattr(jcr->last_fname, current_xattr.name, current_xattr.value,
514                     current_xattr.value_length, 0) != 0) {
515          switch (errno) {
516          case ENOENT:
517             break;
518          default:
519             Mmsg2(jcr->errmsg, _("lsetxattr error on file \"%s\": ERR=%s\n"),
520                   jcr->last_fname, be.bstrerror());
521             Dmsg2(100, "lsetxattr error file=%s ERR=%s\n",
522                   jcr->last_fname, be.bstrerror());
523             retval = bxattr_exit_error;
524             break;
525          }
526       }
527
528       /*
529        * Free the temporary buffers.
530        */
531       free(current_xattr.name);
532       free(current_xattr.value);
533    }
534
535    unser_end(jcr->xattr_data->content, jcr->xattr_data->content_length);
536    return retval;
537 }
538
539 /*
540  * For all these os-es setup the build and parse function pointer to the generic functions.
541  */
542 static bxattr_exit_code (*os_build_xattr_streams)(JCR *jcr, FF_PKT *ff_pkt) = generic_xattr_build_streams;
543 static bxattr_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = generic_xattr_parse_streams;
544
545 #elif defined(HAVE_SUN_OS)
546 /*
547  * Solaris extended attributes were introduced in Solaris 9
548  * by PSARC 1999/209
549  *
550  * Solaris extensible attributes were introduced in OpenSolaris
551  * by PSARC 2007/315 Solaris extensible attributes are also
552  * sometimes called extended system attributes.
553  *
554  * man fsattr(5) on Solaris gives a wealth of info. The most
555  * important bits are:
556  *
557  * Attributes are logically supported as files within the  file
558  * system.   The  file  system  is  therefore augmented with an
559  * orthogonal name space of file attributes. Any file  (includ-
560  * ing  attribute files) can have an arbitrarily deep attribute
561  * tree associated with it. Attribute values  are  accessed  by
562  * file descriptors obtained through a special attribute inter-
563  * face.  This logical view of "attributes as files" allows the
564  * leveraging  of  existing file system interface functionality
565  * to support the construction, deletion, and  manipulation  of
566  * attributes.
567  *
568  * The special files  "."  and  ".."  retain  their  accustomed
569  * semantics within the attribute hierarchy.  The "." attribute
570  * file refers to the current directory and the ".."  attribute
571  * file  refers to the parent directory.  The unnamed directory
572  * at the head of each attribute tree is considered the "child"
573  * of  the  file it is associated with and the ".." file refers
574  * to the associated file.  For  any  non-directory  file  with
575  * attributes,  the  ".." entry in the unnamed directory refers
576  * to a file that is not a directory.
577  *
578  * Conceptually, the attribute model is fully general. Extended
579  * attributes  can  be  any  type of file (doors, links, direc-
580  * tories, and so forth) and can even have their own attributes
581  * (fully  recursive).   As a result, the attributes associated
582  * with a file could be an arbitrarily deep directory hierarchy
583  * where each attribute could have an equally complex attribute
584  * tree associated with it.  Not all implementations  are  able
585  * to,  or  want to, support the full model. Implementation are
586  * therefore permitted to reject operations that are  not  sup-
587  * ported.   For  example,  the implementation for the UFS file
588  * system allows only regular files as attributes (for example,
589  * no sub-directories) and rejects attempts to place attributes
590  * on attributes.
591  *
592  * The following list details the operations that are  rejected
593  * in the current implementation:
594  *
595  * link                     Any attempt to create links between
596  *                          attribute  and  non-attribute space
597  *                          is rejected  to  prevent  security-
598  *                          related   or   otherwise  sensitive
599  *                          attributes from being exposed,  and
600  *                          therefore  manipulable,  as regular
601  *                          files.
602  *
603  * rename                   Any  attempt  to   rename   between
604  *                          attribute  and  non-attribute space
605  *                          is rejected to prevent  an  already
606  *                          linked  file from being renamed and
607  *                          thereby circumventing the link res-
608  *                          triction above.
609  *
610  * mkdir, symlink, mknod    Any  attempt  to  create  a   "non-
611  *                          regular" file in attribute space is
612  *                          rejected to reduce the  functional-
613  *                          ity,  and  therefore  exposure  and
614  *                          risk, of  the  initial  implementa-
615  *                          tion.
616  *
617  * The entire available name space has been allocated to  "gen-
618  * eral use" to bring the implementation in line with the NFSv4
619  * draft standard [NFSv4]. That standard defines "named  attri-
620  * butes"  (equivalent  to Solaris Extended Attributes) with no
621  * naming restrictions.  All Sun  applications  making  use  of
622  * opaque extended attributes will use the prefix "SUNW".
623  *
624  */
625 #ifdef HAVE_SYS_ATTR_H
626 #include <sys/attr.h>
627 #endif
628
629 #ifdef HAVE_ATTR_H
630 #include <attr.h>
631 #endif
632
633 #ifdef HAVE_SYS_NVPAIR_H
634 #include <sys/nvpair.h>
635 #endif
636
637 #ifdef HAVE_SYS_ACL_H
638 #include <sys/acl.h>
639 #endif
640
641 /*
642  * Define the supported XATTR streams for this OS
643  */
644 #if defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED)
645 static int os_default_xattr_streams[2] = { STREAM_XATTR_SOLARIS, STREAM_XATTR_SOLARIS_SYS};
646 #else
647 static int os_default_xattr_streams[1] = { STREAM_XATTR_SOLARIS };
648 #endif /* defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED) */
649
650 /*
651  * This code creates a temporary cache with entries for each xattr which has
652  * a link count > 1 (which indicates it has one or more hard linked counterpart(s))
653  */
654 static xattr_link_cache_entry_t *find_xattr_link_cache_entry(JCR *jcr, ino_t inum)
655 {
656    xattr_link_cache_entry_t *ptr;
657
658    foreach_alist(ptr, jcr->xattr_data->link_cache) {
659       if (ptr && ptr->inum == inum) {
660          return ptr;
661       }
662    }
663    return NULL;
664 }
665
666 static void add_xattr_link_cache_entry(JCR *jcr, ino_t inum, char *target)
667 {
668    xattr_link_cache_entry_t *ptr;
669
670    ptr = (xattr_link_cache_entry_t *)malloc(sizeof(xattr_link_cache_entry_t));
671    memset((caddr_t)ptr, 0, sizeof(xattr_link_cache_entry_t));
672    ptr->inum = inum;
673    bstrncpy(ptr->target, target, sizeof(ptr->target));
674    jcr->xattr_data->link_cache->append(ptr);
675 }
676
677 static void flush_xattr_link_cache(JCR *jcr)
678 {
679    xattr_link_cache_entry_t *ptr;
680
681    foreach_alist(ptr, jcr->xattr_data->link_cache) {
682       if (ptr && ptr->target) {
683          free(ptr->target);
684       }
685    }
686 }
687
688 #if defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED)
689 /*
690  * This function returns true if a non default extended system attribute
691  * list is associated with fd and returns false when an error has occured
692  * or when only extended system attributes other than archive,
693  * av_modified or crtime are set.
694  *
695  * The function returns true for the following cases:
696  *
697  * - any extended system attribute other than the default attributes
698  *   ('archive', 'av_modified' and 'crtime') is set
699  * - nvlist has NULL name string
700  * - nvpair has data type of 'nvlist'
701  * - default data type.
702  */
703 static bool solaris_has_non_transient_extensible_attributes(int fd)
704 {
705    boolean_t value;
706    data_type_t type;
707    nvlist_t *response;
708    nvpair_t *pair;
709    f_attr_t fattr;
710    char *name;
711    bool retval = false;
712
713    if (fgetattr(fd, XATTR_VIEW_READWRITE, &response) != 0) {
714       return false;
715    }
716
717    pair = NULL;
718    while ((pair = nvlist_next_nvpair(response, pair)) != NULL) {
719       name = nvpair_name(pair);
720
721       if (name != NULL) {
722          fattr = name_to_attr(name);
723       } else {
724          retval = true;
725          goto bail_out;
726       }
727
728       type = nvpair_type(pair);
729       switch (type) {
730       case DATA_TYPE_BOOLEAN_VALUE:
731          if (nvpair_value_boolean_value(pair, &value) != 0) {
732             continue;
733          }
734          if (value && fattr != F_ARCHIVE &&
735                       fattr != F_AV_MODIFIED) {
736             retval = true;
737             goto bail_out;
738          }
739          break;
740       case DATA_TYPE_UINT64_ARRAY:
741          if (fattr != F_CRTIME) {
742             retval = true;
743             goto bail_out;
744          }
745          break;
746       case DATA_TYPE_NVLIST:
747       default:
748          retval = true;
749          goto bail_out;
750       }
751    }
752
753 bail_out:
754    if (response != NULL) {
755       nvlist_free(response);
756    }
757    return retval;
758 }
759 #endif /* HAVE_SYS_NVPAIR_H && _PC_SATTR_ENABLED */
760
761 #if defined(HAVE_ACL) && !defined(HAVE_EXTENDED_ACL)
762 /*
763  * See if an acl is a trivial one (e.g. just the stat bits encoded as acl.)
764  * There is no need to store those acls as we already store the stat bits too.
765  */
766 static bool acl_is_trivial(int count, aclent_t *entries)
767 {
768    int n;
769    aclent_t *ace;
770
771    for (n = 0; n < count; n++) {
772       ace = &entries[n];
773       if (!(ace->a_type == USER_OBJ ||
774             ace->a_type == GROUP_OBJ ||
775             ace->a_type == OTHER_OBJ ||
776             ace->a_type == CLASS_OBJ))
777         return false;
778    }
779    return true;
780 }
781 #endif /* HAVE_ACL && !HAVE_EXTENDED_ACL */
782
783 static bxattr_exit_code solaris_save_xattr_acl(JCR *jcr, int fd, const char *attrname, char **acl_text)
784 {
785 #ifdef HAVE_ACL
786 #ifdef HAVE_EXTENDED_ACL
787    int flags;
788    acl_t *aclp = NULL;
789    berrno be;
790
791    /*
792     * See if this attribute has an ACL
793     */
794    if ((fd != -1 && fpathconf(fd, _PC_ACL_ENABLED) > 0) ||
795        pathconf(attrname, _PC_ACL_ENABLED) > 0) {
796       /*
797        * See if there is a non trivial acl on the file.
798        */
799       if ((fd != -1 && facl_get(fd, ACL_NO_TRIVIAL, &aclp) != 0) ||
800            acl_get(attrname, ACL_NO_TRIVIAL, &aclp) != 0) {
801          switch (errno) {
802          case ENOENT:
803             return bxattr_exit_ok;
804          default:
805             Mmsg3(jcr->errmsg, _("Unable to get acl on xattr %s on file \"%s\": ERR=%s\n"),
806                   attrname, jcr->last_fname, be.bstrerror());
807             Dmsg3(100, "facl_get/acl_get of xattr %s on \"%s\" failed: ERR=%s\n",
808                   attrname, jcr->last_fname, be.bstrerror());
809             return bxattr_exit_error;
810          }
811       }
812
813       if (aclp != NULL) {
814 #if defined(ACL_SID_FMT)
815          /*
816           * New format flag added in newer Solaris versions.
817           */
818          flags = ACL_APPEND_ID | ACL_COMPACT_FMT | ACL_SID_FMT;
819 #else
820          flags = ACL_APPEND_ID | ACL_COMPACT_FMT;
821 #endif /* ACL_SID_FMT */
822
823          *acl_text = acl_totext(aclp, flags);
824          acl_free(aclp);
825       } else {
826          *acl_text = NULL;
827       }
828    } else {
829       *acl_text = NULL;
830    }
831    return bxattr_exit_ok;
832 #else /* HAVE_EXTENDED_ACL */
833    int n;
834    aclent_t *acls = NULL;
835    berrno be;
836
837    /*
838     * See if this attribute has an ACL
839     */
840    if (fd != -1) {
841       n = facl(fd, GETACLCNT, 0, NULL);
842    } else {
843       n = acl(attrname, GETACLCNT, 0, NULL);
844    }
845
846    if (n >= MIN_ACL_ENTRIES) {
847       acls = (aclent_t *)malloc(n * sizeof(aclent_t));
848       if ((fd != -1 && facl(fd, GETACL, n, acls) != n) ||
849           acl(attrname, GETACL, n, acls) != n) {
850          switch (errno) {
851          case ENOENT:
852             free(acls);
853             return bxattr_exit_ok;
854          default:
855             Mmsg3(jcr->errmsg, _("Unable to get acl on xattr %s on file \"%s\": ERR=%s\n"),
856                   attrname, jcr->last_fname, be.bstrerror());
857             Dmsg3(100, "facl/acl of xattr %s on \"%s\" failed: ERR=%s\n",
858                   attrname, jcr->last_fname, be.bstrerror());
859             free(acls);
860             return bxattr_exit_error;
861          }
862       }
863
864       /*
865        * See if there is a non trivial acl on the file.
866        */
867       if (!acl_is_trivial(n, acls)) {
868          if ((*acl_text = acltotext(acls, n)) == NULL) {
869             Mmsg3(jcr->errmsg, _("Unable to get acl text on xattr %s on file \"%s\": ERR=%s\n"),
870                   attrname, jcr->last_fname, be.bstrerror());
871             Dmsg3(100, "acltotext of xattr %s on \"%s\" failed: ERR=%s\n",
872                   attrname, jcr->last_fname, be.bstrerror());
873             free(acls);
874             return bxattr_exit_error;
875          }
876       } else {
877          *acl_text = NULL;
878       }
879
880      free(acls);
881    } else {
882       *acl_text = NULL;
883    }
884    return bxattr_exit_ok;
885 #endif /* HAVE_EXTENDED_ACL */
886
887 #else /* HAVE_ACL */
888    return bxattr_exit_ok;
889 #endif /* HAVE_ACL */
890 }
891
892 /*
893  * Forward declaration for recursive function call.
894  */
895 static bxattr_exit_code solaris_save_xattrs(JCR *jcr, const char *xattr_namespace, const char *attr_parent);
896
897 /*
898  * Save an extended or extensible attribute.
899  * This is stored as an opaque stream of bytes with the following encoding:
900  *
901  * <xattr_name>\0<stat_buffer>\0<acl_string>\0<actual_xattr_data>
902  * 
903  * or for a hardlinked or symlinked attribute
904  *
905  * <xattr_name>\0<stat_buffer>\0<xattr_link_source>\0
906  *
907  * xattr_name can be a subpath relative to the file the xattr is on.
908  * stat_buffer is the string representation of the stat struct.
909  * acl_string is an acl text when a non trivial acl is set on the xattr.
910  * actual_xattr_data is the content of the xattr file.
911  */
912 static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_namespace,
913                                            const char *attrname, bool toplevel_hidden_dir, int stream)
914 {
915    int cnt;
916    int attrfd = -1;
917    struct stat st;
918    xattr_link_cache_entry_t *xlce;
919    char target_attrname[PATH_MAX];
920    char link_source[PATH_MAX];
921    char *acl_text = NULL;
922    char attribs[MAXSTRING];
923    char buffer[BUFSIZ];
924    bxattr_exit_code retval = bxattr_exit_error;
925    berrno be;
926
927    bsnprintf(target_attrname, sizeof(target_attrname), "%s%s", xattr_namespace, attrname);
928
929    /*
930     * Get the stats of the extended or extensible attribute.
931     */
932    if (fstatat(fd, attrname, &st, AT_SYMLINK_NOFOLLOW) < 0) {
933       switch (errno) {
934       case ENOENT:
935          retval = bxattr_exit_ok;
936          goto bail_out;
937       default:
938          Mmsg3(jcr->errmsg, _("Unable to get status on xattr %s on file \"%s\": ERR=%s\n"),
939                target_attrname, jcr->last_fname, be.bstrerror());
940          Dmsg3(100, "fstatat of xattr %s on \"%s\" failed: ERR=%s\n",
941                target_attrname, jcr->last_fname, be.bstrerror());
942          goto bail_out;
943       }
944    }
945
946    /*
947     * Based on the filetype perform the correct action. We support most filetypes here, more
948     * then the actual implementation on Solaris supports so some code may never get executed
949     * due to limitations in the implementation.
950     */
951    switch (st.st_mode & S_IFMT) {
952    case S_IFIFO:
953    case S_IFCHR:
954    case S_IFBLK:
955       /*
956        * Get any acl on the xattr.
957        */
958       if (solaris_save_xattr_acl(jcr, attrfd, attrname, &acl_text) != bxattr_exit_ok)
959          goto bail_out;
960
961       /*
962        * The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared.
963        * Encode the stat struct into an ASCII representation.
964        */
965       encode_stat(attribs, &st, 0, stream);
966       cnt = bsnprintf(buffer, sizeof(buffer), "%s%c%s%c%s%c",
967                      target_attrname, 0, attribs, 0, (acl_text) ? acl_text : "", 0);
968       break;
969    case S_IFDIR:
970       /*
971        * Get any acl on the xattr.
972        */
973       if (solaris_save_xattr_acl(jcr, attrfd, attrname, &acl_text) != bxattr_exit_ok)
974          goto bail_out;
975
976       /*
977        * See if this is the toplevel_hidden_dir being saved.
978        */
979       if (toplevel_hidden_dir) {
980          /*
981           * Save the data for later storage when we encounter a real xattr. We store the data
982           * in the jcr->xattr_data->content buffer and flush that just before sending out the
983           * first real xattr. Encode the stat struct into an ASCII representation and jump
984           * out of the function.
985           */
986          encode_stat(attribs, &st, 0, stream);
987          cnt = bsnprintf(buffer, sizeof(buffer),
988                          "%s%c%s%c%s%c",
989                          target_attrname, 0, attribs, 0, (acl_text) ? acl_text : "", 0);
990          pm_memcpy(jcr->xattr_data->content, buffer, cnt);
991          jcr->xattr_data->content_length = cnt;
992          goto bail_out;
993       } else {
994          /*
995           * The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared.
996           * Encode the stat struct into an ASCII representation.
997           */
998          encode_stat(attribs, &st, 0, stream);
999          cnt = bsnprintf(buffer, sizeof(buffer),
1000                          "%s%c%s%c%s%c",
1001                          target_attrname, 0, attribs, 0, (acl_text) ? acl_text : "", 0);
1002       }
1003       break;
1004    case S_IFREG:
1005       /*
1006        * If this is a hardlinked file check the inode cache for a hit.
1007        */
1008       if (st.st_nlink > 1) {
1009          /*
1010           * See if the cache already knows this inode number.
1011           */
1012          if ((xlce = find_xattr_link_cache_entry(jcr, st.st_ino)) != NULL) {
1013             /*
1014              * Generate a xattr encoding with the reference to the target in there.
1015              */
1016             encode_stat(attribs, &st, st.st_ino, stream);
1017             cnt = bsnprintf(buffer, sizeof(buffer),
1018                             "%s%c%s%c%s%c",
1019                             target_attrname, 0, attribs, 0, xlce->target, 0);
1020             pm_memcpy(jcr->xattr_data->content, buffer, cnt);
1021             jcr->xattr_data->content_length = cnt;
1022             retval = send_xattr_stream(jcr, stream);
1023
1024             /*
1025              * For a hard linked file we are ready now, no need to recursively save the attributes.
1026              */
1027             goto bail_out;
1028          }
1029
1030          /*
1031           * Store this hard linked file in the cache.
1032           * Store the name relative to the top level xattr space.
1033           */
1034          add_xattr_link_cache_entry(jcr, st.st_ino, target_attrname + 1);
1035       }
1036
1037       /*
1038        * Get any acl on the xattr.
1039        */
1040       if (solaris_save_xattr_acl(jcr, attrfd, attrname, &acl_text) != bxattr_exit_ok) {
1041          goto bail_out;
1042       }
1043
1044       /*
1045        * Encode the stat struct into an ASCII representation.
1046        */
1047       encode_stat(attribs, &st, 0, stream);
1048       cnt = bsnprintf(buffer, sizeof(buffer),
1049                      "%s%c%s%c%s%c",
1050                      target_attrname, 0, attribs, 0, (acl_text) ? acl_text : "", 0);
1051
1052       /*
1053        * Open the extended or extensible attribute file.
1054        */
1055       if ((attrfd = openat(fd, attrname, O_RDONLY)) < 0) {
1056          switch (errno) {
1057          case ENOENT:
1058             retval = bxattr_exit_ok;
1059             goto bail_out;
1060          default:
1061             Mmsg3(jcr->errmsg, _("Unable to open xattr %s on \"%s\": ERR=%s\n"),
1062                   target_attrname, jcr->last_fname, be.bstrerror());
1063             Dmsg3(100, "openat of xattr %s on \"%s\" failed: ERR=%s\n",
1064                   target_attrname, jcr->last_fname, be.bstrerror());
1065             goto bail_out;
1066          }
1067       }
1068       break;
1069    case S_IFLNK:
1070       /*
1071        * The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared.
1072        * Encode the stat struct into an ASCII representation.
1073        */
1074       if (readlink(attrname, link_source, sizeof(link_source)) < 0) {
1075          switch (errno) {
1076          case ENOENT:
1077             retval = bxattr_exit_ok;
1078             goto bail_out;
1079          default:
1080             Mmsg3(jcr->errmsg, _("Unable to read symlin %s on \"%s\": ERR=%s\n"),
1081                   target_attrname, jcr->last_fname, be.bstrerror());
1082             Dmsg3(100, "readlink of xattr %s on \"%s\" failed: ERR=%s\n",
1083                   target_attrname, jcr->last_fname, be.bstrerror());
1084             goto bail_out;
1085          }
1086       }
1087
1088       /*
1089        * Generate a xattr encoding with the reference to the target in there.
1090        */
1091       encode_stat(attribs, &st, st.st_ino, stream);
1092       cnt = bsnprintf(buffer, sizeof(buffer),
1093                       "%s%c%s%c%s%c",
1094                       target_attrname, 0, attribs, 0, link_source, 0);
1095       pm_memcpy(jcr->xattr_data->content, buffer, cnt);
1096       jcr->xattr_data->content_length = cnt;
1097       retval = send_xattr_stream(jcr, stream);
1098
1099       if (retval == bxattr_exit_ok) {
1100          jcr->xattr_data->nr_saved++;
1101       }
1102
1103       /*
1104        * For a soft linked file we are ready now, no need to recursively save the attributes.
1105        */
1106       goto bail_out;
1107    default:
1108       goto bail_out;
1109    }
1110
1111    /*
1112     * See if this is the first real xattr being saved.
1113     * If it is save the toplevel_hidden_dir attributes first.
1114     * This is easy as its stored already in the jcr->xattr_data->content buffer.
1115     */
1116    if (jcr->xattr_data->nr_saved == 0) {
1117       retval = send_xattr_stream(jcr, STREAM_XATTR_SOLARIS);
1118       if (retval != bxattr_exit_ok) {
1119          goto bail_out;
1120       }
1121       jcr->xattr_data->nr_saved++;
1122    }
1123
1124    pm_memcpy(jcr->xattr_data->content, buffer, cnt);
1125    jcr->xattr_data->content_length = cnt;
1126
1127    /*
1128     * Only dump the content of regular files.
1129     */
1130    switch (st.st_mode & S_IFMT) {
1131    case S_IFREG:
1132       if (st.st_size > 0) {
1133          /*
1134           * Protect ourself against things getting out of hand.
1135           */
1136          if (st.st_size >= MAX_XATTR_STREAM) {
1137             Mmsg2(jcr->errmsg, _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"),
1138                   jcr->last_fname, MAX_XATTR_STREAM);
1139             goto bail_out;
1140          }
1141
1142          while ((cnt = read(attrfd, buffer, sizeof(buffer))) > 0) {
1143             jcr->xattr_data->content = check_pool_memory_size(jcr->xattr_data->content, jcr->xattr_data->content_length + cnt);
1144             memcpy(jcr->xattr_data->content + jcr->xattr_data->content_length, buffer, cnt);
1145             jcr->xattr_data->content_length += cnt;
1146          }
1147
1148          if (cnt < 0) {
1149             Mmsg2(jcr->errmsg, _("Unable to read content of xattr %s on file \"%s\"\n"),
1150                   target_attrname, jcr->last_fname);
1151             Dmsg2(100, "read of data from xattr %s on \"%s\" failed\n",
1152                   target_attrname, jcr->last_fname);
1153             goto bail_out;
1154          }
1155       }
1156       break;
1157
1158    default:
1159       break;
1160    }
1161
1162    if (retval) {
1163       retval = send_xattr_stream(jcr, stream);
1164       if (retval == bxattr_exit_ok) {
1165          jcr->xattr_data->nr_saved++;
1166       }
1167    }
1168
1169    /*
1170     * Recursivly call solaris_save_extended_attributes for archiving the attributes
1171     * available on this extended attribute.
1172     */
1173    if (retval) {
1174       retval = solaris_save_xattrs(jcr, xattr_namespace, attrname);
1175       
1176       /*
1177        * The recursive call could change our working dir so change back to the wanted workdir.
1178        */
1179       if (fchdir(fd) < 0) {
1180          switch (errno) {
1181          case ENOENT:
1182             retval = bxattr_exit_ok;
1183             goto bail_out;
1184          default:
1185             Mmsg2(jcr->errmsg, _("Unable to chdir to xattr space of file \"%s\": ERR=%s\n"),
1186                   jcr->last_fname, be.bstrerror());
1187             Dmsg3(100, "Unable to fchdir to xattr space of file \"%s\" using fd %d: ERR=%s\n",
1188                   jcr->last_fname, fd, be.bstrerror());
1189             goto bail_out;
1190          }
1191       }
1192    }
1193
1194 bail_out:
1195    if (acl_text) {
1196       free(acl_text);
1197    }
1198    if (attrfd != -1) {
1199       close(attrfd);
1200    }
1201    return retval;
1202 }
1203
1204 static bxattr_exit_code solaris_save_xattrs(JCR *jcr, const char *xattr_namespace, const char *attr_parent)
1205 {
1206    const char *name;
1207    int fd, filefd = -1, attrdirfd = -1;
1208    DIR *dirp;
1209    struct dirent *dp;
1210    char current_xattr_namespace[PATH_MAX];
1211    bxattr_exit_code retval = bxattr_exit_error;
1212    berrno be;
1213  
1214    /*
1215     * Determine what argument to use. Use attr_parent when set
1216     * (recursive call) or jcr->last_fname for first call. Also save
1217     * the current depth of the xattr_space we are in.
1218     */
1219    if (attr_parent) {
1220       name = attr_parent;
1221       if (xattr_namespace) {
1222          bsnprintf(current_xattr_namespace, sizeof(current_xattr_namespace), "%s%s/",
1223                    xattr_namespace, attr_parent);
1224       } else {
1225          bstrncpy(current_xattr_namespace, "/", sizeof(current_xattr_namespace));
1226       }
1227    } else {
1228       name = jcr->last_fname;
1229       bstrncpy(current_xattr_namespace, "/", sizeof(current_xattr_namespace));
1230    }
1231
1232    /*
1233     * Open the file on which to save the xattrs read-only.
1234     */
1235    if ((filefd = open(name, O_RDONLY | O_NONBLOCK)) < 0) {
1236       switch (errno) {
1237       case ENOENT:
1238          retval = bxattr_exit_ok;
1239          goto bail_out;
1240       default:
1241          Mmsg2(jcr->errmsg, _("Unable to open file \"%s\": ERR=%s\n"),
1242                jcr->last_fname, be.bstrerror());
1243          Dmsg2(100, "Unable to open file \"%s\": ERR=%s\n",
1244                jcr->last_fname, be.bstrerror());
1245          goto bail_out;
1246       }
1247    }
1248
1249    /*
1250     * Open the xattr naming space.
1251     */
1252    if ((attrdirfd = openat(filefd, ".", O_RDONLY | O_XATTR)) < 0) {
1253       switch (errno) {
1254       case EINVAL:
1255          /*
1256           * Gentile way of the system saying this type of xattr layering is not supported.
1257           * Which is not problem we just forget about this this xattr.
1258           * But as this is not an error we return a positive return value.
1259           */
1260          retval = bxattr_exit_ok;
1261          goto bail_out;
1262       case ENOENT:
1263          retval = bxattr_exit_ok;
1264          goto bail_out;
1265       default:
1266          Mmsg3(jcr->errmsg, _("Unable to open xattr space %s on file \"%s\": ERR=%s\n"),
1267                name, jcr->last_fname, be.bstrerror());
1268          Dmsg3(100, "Unable to open xattr space %s on file \"%s\": ERR=%s\n",
1269                name, jcr->last_fname, be.bstrerror());
1270          goto bail_out;
1271       }
1272    }
1273
1274   /*
1275    * We need to change into the attribute directory to determine if each of the
1276    * attributes should be saved.
1277    */
1278    if (fchdir(attrdirfd) < 0) {
1279       Mmsg2(jcr->errmsg, _("Unable to chdir to xattr space on file \"%s\": ERR=%s\n"),
1280             jcr->last_fname, be.bstrerror());
1281       Dmsg3(100, "Unable to fchdir to xattr space on file \"%s\" using fd %d: ERR=%s\n",
1282             jcr->last_fname, attrdirfd, be.bstrerror());
1283       goto bail_out;
1284    }
1285
1286    /*
1287     * Save the data of the toplevel xattr hidden_dir. We save this one before anything
1288     * else because the readdir returns "." entry after the extensible attr entry.
1289     * And as we want this entry before anything else we better just save its data.
1290     */
1291    if (!attr_parent)
1292       solaris_save_xattr(jcr, attrdirfd, current_xattr_namespace, ".",
1293                          true, STREAM_XATTR_SOLARIS);
1294
1295    if ((fd = dup(attrdirfd)) == -1 ||
1296        (dirp = fdopendir(fd)) == (DIR *)NULL) {
1297       Mmsg2(jcr->errmsg, _("Unable to list the xattr space on file \"%s\": ERR=%s\n"),
1298             jcr->last_fname, be.bstrerror());
1299       Dmsg3(100, "Unable to fdopendir xattr space on file \"%s\" using fd %d: ERR=%s\n",
1300             jcr->last_fname, fd, be.bstrerror());
1301
1302       goto bail_out;
1303    }
1304
1305    /*
1306     * Walk the namespace.
1307     */
1308    while (dp = readdir(dirp)) {
1309       /*
1310        * Skip only the toplevel . dir.
1311        */
1312       if (!attr_parent && !strcmp(dp->d_name, "."))
1313          continue;
1314
1315       /*
1316        * Skip all .. directories
1317        */
1318       if (!strcmp(dp->d_name, ".."))
1319          continue;
1320
1321       Dmsg3(400, "processing extended attribute %s%s on file \"%s\"\n",
1322          current_xattr_namespace, dp->d_name, jcr->last_fname);
1323
1324 #if defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED)
1325       /*
1326        * We are not interested in read-only extensible attributes.
1327        */
1328       if (!strcmp(dp->d_name, VIEW_READONLY)) {
1329          Dmsg3(400, "Skipping readonly extensible attributes %s%s on file \"%s\"\n",
1330             current_xattr_namespace, dp->d_name, jcr->last_fname);
1331
1332          continue;
1333       }
1334
1335       /*
1336        * We are only interested in read-write extensible attributes
1337        * when they contain non-transient values.
1338        */
1339       if (!strcmp(dp->d_name, VIEW_READWRITE)) {
1340          /*
1341           * Determine if there are non-transient system attributes at the toplevel.
1342           * We need to provide a fd to the open file.
1343           */
1344          if (!solaris_has_non_transient_extensible_attributes(filefd)) {
1345             Dmsg3(400, "Skipping transient extensible attributes %s%s on file \"%s\"\n",
1346                current_xattr_namespace, dp->d_name, jcr->last_fname);
1347             continue;
1348          }
1349
1350          /*
1351           * Save the xattr.
1352           */
1353          solaris_save_xattr(jcr, attrdirfd, current_xattr_namespace, dp->d_name,
1354                             false, STREAM_XATTR_SOLARIS_SYS);
1355          continue;
1356       }
1357 #endif /* HAVE_SYS_NVPAIR_H && _PC_SATTR_ENABLED */
1358
1359       /*
1360        * Save the xattr.
1361        */
1362       solaris_save_xattr(jcr, attrdirfd, current_xattr_namespace, dp->d_name,
1363                          false, STREAM_XATTR_SOLARIS);
1364    }
1365
1366    closedir(dirp);
1367    retval = bxattr_exit_ok;
1368
1369 bail_out:
1370    if (attrdirfd != -1)
1371       close(attrdirfd);
1372    if (filefd != -1)
1373       close(filefd);
1374    return retval;
1375 }
1376
1377 #ifdef HAVE_ACL
1378 static bxattr_exit_code solaris_restore_xattr_acl(JCR *jcr, int fd, const char *attrname, char *acl_text)
1379 {
1380 #ifdef HAVE_EXTENDED_ACL
1381    int error;
1382    acl_t *aclp = NULL;
1383    berrno be;
1384
1385    if ((error = acl_fromtext(acl_text, &aclp)) != 0) {
1386       Mmsg1(jcr->errmsg, _("Unable to convert acl from text on file \"%s\"\n"),
1387             jcr->last_fname);
1388       return bxattr_exit_error;
1389    }
1390
1391    if ((fd != -1 && facl_set(fd, aclp) != 0) ||
1392         acl_set(attrname, aclp) != 0) {
1393       Mmsg3(jcr->errmsg, _("Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n"),
1394             attrname, jcr->last_fname, be.bstrerror());
1395       Dmsg3(100, "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n",
1396             attrname, jcr->last_fname, be.bstrerror());
1397       return bxattr_exit_error;
1398    }
1399
1400    if (aclp) {
1401       acl_free(aclp);
1402    }
1403    return bxattr_exit_ok;
1404
1405 #else /* HAVE_EXTENDED_ACL */
1406    int n;
1407    aclent_t *acls = NULL;
1408    berrno be;
1409
1410    acls = aclfromtext(acl_text, &n);
1411    if (!acls) {
1412       if ((fd != -1 && facl(fd, SETACL, n, acls) != 0) ||
1413            acl(attrname, SETACL, n, acls) != 0) {
1414          Mmsg3(jcr->errmsg, _("Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n"),
1415                attrname, jcr->last_fname, be.bstrerror());
1416          Dmsg3(100, "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n",
1417                attrname, jcr->last_fname, be.bstrerror());
1418          return bxattr_exit_error;
1419       }
1420    }
1421
1422    if (acls) {
1423       free(acls);
1424    }
1425    return bxattr_exit_ok;
1426
1427 #endif /* HAVE_EXTENDED_ACL */
1428
1429 }
1430 #endif /* HAVE_ACL */
1431
1432 static bxattr_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible)
1433 {
1434    int fd, filefd = -1, attrdirfd = -1, attrfd = -1;
1435    int used_bytes, total_bytes, cnt;
1436    char *bp, *target_attrname, *attribs;
1437    char *linked_target = NULL;
1438    char *acl_text = NULL;
1439    char *data = NULL;
1440    int32_t inum;
1441    struct stat st;
1442    struct timeval times[2];
1443    bxattr_exit_code retval = bxattr_exit_error;
1444    berrno be;
1445
1446    /*
1447     * Parse the xattr stream. First the part that is the same for all xattrs.
1448     */
1449    used_bytes = 0;
1450    total_bytes = jcr->xattr_data->content_length;
1451
1452    /*
1453     * The name of the target xattr has a leading / we are not interested
1454     * in that so skip it when decoding the string. We always start a the /
1455     * of the xattr space anyway.
1456     */
1457    target_attrname = jcr->xattr_data->content + 1;
1458    if ((bp = strchr(target_attrname, '\0')) == (char *)NULL ||
1459        (used_bytes = (bp - jcr->xattr_data->content)) >= (total_bytes - 1)) {
1460       goto parse_error;
1461    }
1462    attribs = ++bp;
1463
1464    /*
1465     * Open the file on which to restore the xattrs read-only.
1466     */
1467    if ((filefd = open(jcr->last_fname, O_RDONLY | O_NONBLOCK)) < 0) {
1468       Mmsg2(jcr->errmsg, _("Unable to open file \"%s\": ERR=%s\n"),
1469             jcr->last_fname, be.bstrerror());
1470       Dmsg2(100, "Unable to open file \"%s\": ERR=%s\n",
1471             jcr->last_fname, be.bstrerror());
1472       goto bail_out;
1473    }
1474
1475    /*
1476     * Open the xattr naming space and make it the current working dir.
1477     */
1478    if ((attrdirfd = openat(filefd, ".", O_RDONLY | O_XATTR)) < 0) {
1479       Mmsg2(jcr->errmsg, _("Unable to open xattr space on file \"%s\": ERR=%s\n"),
1480             jcr->last_fname, be.bstrerror());
1481       Dmsg2(100, "Unable to open xattr space on file \"%s\": ERR=%s\n",
1482             jcr->last_fname, be.bstrerror());
1483       goto bail_out;
1484    }
1485
1486    if (fchdir(attrdirfd) < 0) {
1487       Mmsg2(jcr->errmsg, _("Unable to chdir to xattr space on file \"%s\": ERR=%s\n"),
1488             jcr->last_fname, be.bstrerror());
1489       Dmsg3(100, "Unable to fchdir to xattr space on file \"%s\" using fd %d: ERR=%s\n",
1490             jcr->last_fname, attrdirfd, be.bstrerror());
1491       goto bail_out;
1492    }
1493
1494    /*
1495     * Try to open the correct xattr subdir based on the target_attrname given.
1496     * e.g. check if its a subdir attrname. Each / in the string makes us go
1497     * one level deeper.
1498     */
1499    while ((bp = strchr(target_attrname, '/')) != (char *)NULL) {
1500       *bp = '\0';
1501
1502       if ((fd = open(target_attrname, O_RDONLY | O_NONBLOCK)) < 0) {
1503          Mmsg3(jcr->errmsg, _("Unable to open xattr %s on file \"%s\": ERR=%s\n"),
1504                target_attrname, jcr->last_fname, be.bstrerror());
1505          Dmsg3(100, "Unable to open xattr %s on file \"%s\": ERR=%s\n",
1506                target_attrname, jcr->last_fname, be.bstrerror());
1507          goto bail_out;
1508       }
1509
1510       close(filefd);
1511       filefd = fd;
1512
1513       /*
1514        * Open the xattr naming space.
1515        */
1516       if ((fd = openat(filefd, ".", O_RDONLY | O_XATTR)) < 0) {
1517          Mmsg3(jcr->errmsg, _("Unable to open xattr space %s on file \"%s\": ERR=%s\n"),
1518                target_attrname, jcr->last_fname, be.bstrerror());
1519          Dmsg3(100, "Unable to open xattr space %s on file \"%s\": ERR=%s\n",
1520                target_attrname, jcr->last_fname, be.bstrerror());
1521          goto bail_out;
1522       }
1523
1524       close(attrdirfd);
1525       attrdirfd = fd;
1526
1527       /*
1528        * Make the xattr space our current workingdir.
1529        */
1530       if (fchdir(attrdirfd) < 0) {
1531          Mmsg3(jcr->errmsg, _("Unable to chdir to xattr space %s on file \"%s\": ERR=%s\n"),
1532                target_attrname, jcr->last_fname, be.bstrerror());
1533          Dmsg4(100, "Unable to fchdir to xattr space %s on file \"%s\" using fd %d: ERR=%s\n",
1534                target_attrname, jcr->last_fname, attrdirfd, be.bstrerror());
1535          goto bail_out;
1536       }
1537
1538       target_attrname = ++bp;
1539    }
1540
1541    /*
1542     * Decode the attributes from the stream.
1543     */
1544    decode_stat(attribs, &st, &inum);
1545
1546    /*
1547     * Decode the next field (acl_text).
1548     */
1549    if ((bp = strchr(attribs, '\0')) == (char *)NULL ||
1550        (used_bytes = (bp - jcr->xattr_data->content)) >= (total_bytes - 1)) {
1551       goto parse_error;
1552    }
1553    acl_text = ++bp;
1554
1555    /*
1556     * Based on the filetype perform the correct action. We support most filetypes here, more
1557     * then the actual implementation on Solaris supports so some code may never get executed
1558     * due to limitations in the implementation.
1559     */
1560    switch (st.st_mode & S_IFMT) {
1561    case S_IFIFO:
1562       /*
1563        * The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared.
1564        */
1565       unlinkat(attrdirfd, target_attrname, 0);
1566       if (mkfifo(target_attrname, st.st_mode) < 0) {
1567          Mmsg3(jcr->errmsg, _("Unable to mkfifo xattr %s on file \"%s\": ERR=%s\n"),
1568                target_attrname, jcr->last_fname, be.bstrerror());
1569          Dmsg3(100, "Unable to mkfifo xattr %s on file \"%s\": ERR=%s\n",
1570                target_attrname,  jcr->last_fname, be.bstrerror());
1571          goto bail_out;
1572       }
1573       break;
1574    case S_IFCHR:
1575    case S_IFBLK:
1576       /*
1577        * The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared.
1578        */
1579       unlinkat(attrdirfd, target_attrname, 0);
1580       if (mknod(target_attrname, st.st_mode, st.st_rdev) < 0) {
1581          Mmsg3(jcr->errmsg, _("Unable to mknod xattr %s on file \"%s\": ERR=%s\n"),
1582                target_attrname, jcr->last_fname, be.bstrerror());
1583          Dmsg3(100, "Unable to mknod xattr %s on file \"%s\": ERR=%s\n",
1584                target_attrname,  jcr->last_fname, be.bstrerror());
1585          goto bail_out;
1586       }
1587       break;
1588    case S_IFDIR:
1589       /*
1590        * If its not the hidden_dir create the entry.
1591        * The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared.
1592        */
1593       if (strcmp(target_attrname, ".")) {
1594          unlinkat(attrdirfd, target_attrname, AT_REMOVEDIR);
1595          if (mkdir(target_attrname, st.st_mode) < 0) {
1596             Jmsg3(jcr, M_WARNING, 0, _("Unable to mkdir xattr %s on file \"%s\": ERR=%s\n"),
1597                target_attrname, jcr->last_fname, be.bstrerror());
1598             Dmsg3(100, "Unable to mkdir xattr %s on file \"%s\": ERR=%s\n",
1599                target_attrname,  jcr->last_fname, be.bstrerror());
1600             goto bail_out;
1601          }
1602       }
1603       break;
1604    case S_IFREG:
1605       /*
1606        * See if this is a hard linked file. e.g. inum != 0
1607        */
1608       if (inum != 0) {
1609          linked_target = bp;
1610
1611          unlinkat(attrdirfd, target_attrname, 0);
1612          if (link(linked_target, target_attrname) < 0) {
1613             Mmsg4(jcr->errmsg, _("Unable to link xattr %s to %s on file \"%s\": ERR=%s\n"),
1614                   target_attrname, linked_target, jcr->last_fname, be.bstrerror());
1615             Dmsg4(100, "Unable to link xattr %s to %s on file \"%s\": ERR=%s\n",
1616                   target_attrname, linked_target, jcr->last_fname, be.bstrerror());
1617             goto bail_out;
1618          }
1619
1620          /*
1621           * Successfully restored xattr.
1622           */
1623          retval = bxattr_exit_ok;
1624          goto bail_out;
1625       } else {
1626          if ((bp = strchr(acl_text, '\0')) == (char *)NULL ||
1627              (used_bytes = (bp - jcr->xattr_data->content)) >= total_bytes) {
1628             goto parse_error;
1629          }
1630
1631          if (used_bytes < (total_bytes - 1))
1632             data = ++bp;
1633
1634          /*
1635           * Restore the actual xattr.
1636           */
1637          if (!is_extensible) {
1638             unlinkat(attrdirfd, target_attrname, 0);
1639          }
1640
1641          if ((attrfd = openat(attrdirfd, target_attrname, O_RDWR | O_CREAT | O_TRUNC, st.st_mode)) < 0) {
1642             Mmsg3(jcr->errmsg, _("Unable to open xattr %s on file \"%s\": ERR=%s\n"),
1643                   target_attrname, jcr->last_fname, be.bstrerror());
1644             Dmsg3(100, "Unable to open xattr %s on file \"%s\": ERR=%s\n",
1645                   target_attrname, jcr->last_fname, be.bstrerror());
1646             goto bail_out;
1647          }
1648       }
1649
1650       /*
1651        * Restore the actual data.
1652        */
1653       if (st.st_size > 0) {
1654          used_bytes = (data - jcr->xattr_data->content);
1655          cnt = total_bytes - used_bytes;
1656
1657          /*
1658           * Do a sanity check, the st.st_size should be the same as the number of bytes
1659           * we have available as data of the stream.
1660           */
1661          if (cnt != st.st_size) {
1662             Mmsg2(jcr->errmsg, _("Unable to restore data of xattr %s on file \"%s\": Not all data available in xattr stream\n"),
1663                   target_attrname, jcr->last_fname);
1664             Dmsg2(100, "Unable to restore data of xattr %s on file \"%s\": Not all data available in xattr stream\n",
1665                   target_attrname, jcr->last_fname);
1666             goto bail_out;
1667          }
1668
1669          while (cnt > 0) {
1670             cnt = write(attrfd, data, cnt);
1671             if (cnt < 0) {
1672                Mmsg3(jcr->errmsg, _("Unable to restore data of xattr %s on file \"%s\": ERR=%s\n"),
1673                      target_attrname, jcr->last_fname, be.bstrerror());
1674                Dmsg3(100, "Unable to restore data of xattr %s on file \"%s\": ERR=%s\n",
1675                      target_attrname, jcr->last_fname, be.bstrerror());
1676                goto bail_out;
1677             }
1678
1679             used_bytes += cnt;
1680             data += cnt;
1681             cnt = total_bytes - used_bytes;
1682          }
1683       }
1684       break;
1685    case S_IFLNK:
1686       /*
1687        * The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared.
1688        */
1689       linked_target = bp;
1690
1691       if (symlink(linked_target, target_attrname) < 0) {
1692          Mmsg4(jcr->errmsg, _("Unable to symlink xattr %s to %s on file \"%s\": ERR=%s\n"),
1693                target_attrname, linked_target, jcr->last_fname, be.bstrerror());
1694          Dmsg4(100, "Unable to symlink xattr %s to %s on file \"%s\": ERR=%s\n",
1695                target_attrname, linked_target, jcr->last_fname, be.bstrerror());
1696          goto bail_out;
1697       }
1698
1699       /*
1700        * Successfully restored xattr.
1701        */
1702       retval = bxattr_exit_ok;
1703       goto bail_out;
1704    default:
1705       goto bail_out;
1706    }
1707
1708    /*
1709     * Restore owner and acl for non extensible attributes.
1710     */
1711    if (!is_extensible) {
1712       if (fchownat(attrdirfd, target_attrname, st.st_uid, st.st_gid, AT_SYMLINK_NOFOLLOW) < 0) {
1713          switch (errno) {
1714          case EINVAL:
1715             /*
1716              * Gentile way of the system saying this type of xattr layering is not supported.
1717              * But as this is not an error we return a positive return value.
1718              */
1719             retval = bxattr_exit_ok;
1720             break;
1721          case ENOENT:
1722             retval = bxattr_exit_ok;
1723             break;
1724          default:
1725             Mmsg3(jcr->errmsg, _("Unable to restore owner of xattr %s on file \"%s\": ERR=%s\n"),
1726                   target_attrname, jcr->last_fname, be.bstrerror());
1727             Dmsg3(100, "Unable to restore owner of xattr %s on file \"%s\": ERR=%s\n",
1728                   target_attrname, jcr->last_fname, be.bstrerror());
1729          }
1730          goto bail_out;
1731       }
1732    }
1733
1734 #ifdef HAVE_ACL
1735    if (acl_text && *acl_text)
1736       if (solaris_restore_xattr_acl(jcr, attrfd, target_attrname, acl_text) != bxattr_exit_ok)
1737          goto bail_out;
1738 #endif /* HAVE_ACL */
1739
1740    /*
1741     * For a non extensible attribute restore access and modification time on the xattr.
1742     */
1743    if (!is_extensible) {
1744       times[0].tv_sec = st.st_atime;
1745       times[0].tv_usec = 0;
1746       times[1].tv_sec = st.st_mtime;
1747       times[1].tv_usec = 0;
1748
1749       if (futimesat(attrdirfd, target_attrname, times) < 0) {
1750          Mmsg3(jcr->errmsg, _("Unable to restore filetimes of xattr %s on file \"%s\": ERR=%s\n"),
1751                target_attrname, jcr->last_fname, be.bstrerror());
1752          Dmsg3(100, "Unable to restore filetimes of xattr %s on file \"%s\": ERR=%s\n",
1753                target_attrname, jcr->last_fname, be.bstrerror());
1754          goto bail_out;
1755       }
1756    }
1757
1758    /*
1759     * Successfully restored xattr.
1760     */
1761    retval = bxattr_exit_ok;
1762    goto bail_out;
1763
1764 parse_error:
1765    Mmsg1(jcr->errmsg, _("Illegal xattr stream, failed to parse xattr stream on file \"%s\"\n"),
1766          jcr->last_fname);
1767    Dmsg1(100, "Illegal xattr stream, failed to parse xattr stream on file \"%s\"\n",
1768          jcr->last_fname);
1769
1770 bail_out:
1771    if (attrfd != -1) {
1772       close(attrfd);
1773    }
1774    if (attrdirfd != -1) {
1775       close(attrdirfd);
1776    }
1777    if (filefd != -1) {
1778       close(filefd);
1779    }
1780    return retval;
1781 }
1782
1783 static bxattr_exit_code solaris_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
1784 {
1785    char cwd[PATH_MAX];
1786    bxattr_exit_code retval = bxattr_exit_ok;
1787
1788    /*
1789     * First see if extended attributes or extensible attributes are present.
1790     * If not just pretend things went ok.
1791     */
1792    if (pathconf(jcr->last_fname, _PC_XATTR_EXISTS) > 0) {
1793       jcr->xattr_data->nr_saved = 0;
1794       jcr->xattr_data->link_cache = New(alist(10, not_owned_by_alist));
1795
1796       /*
1797        * As we change the cwd in the save function save the current cwd
1798        * for restore after return from the solaris_save_xattrs function.
1799        */
1800       getcwd(cwd, sizeof(cwd));
1801       retval = solaris_save_xattrs(jcr, NULL, NULL);
1802       chdir(cwd);
1803       flush_xattr_link_cache(jcr);
1804       delete jcr->xattr_data->link_cache;
1805       jcr->xattr_data->link_cache = NULL;
1806    }
1807    return retval;
1808 }
1809
1810 static bxattr_exit_code solaris_parse_xattr_streams(JCR *jcr, int stream)
1811 {
1812    char cwd[PATH_MAX];
1813    bool is_extensible = false;
1814    bxattr_exit_code retval;
1815
1816    /*
1817     * First make sure we can restore xattr on the filesystem.
1818     */
1819    switch (stream) {
1820 #if defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED)
1821    case STREAM_XATTR_SOLARIS_SYS:
1822       if (pathconf(jcr->last_fname, _PC_SATTR_ENABLED) <= 0) {
1823          Qmsg1(jcr, M_WARNING, 0,
1824                _("Failed to restore extensible attributes on file \"%s\"\n"),
1825                jcr->last_fname);
1826          Dmsg1(100, "Unable to restore extensible attributes on file \"%s\", filesystem doesn't support this\n",
1827             jcr->last_fname);
1828          return bxattr_exit_error;
1829       }
1830
1831       is_extensible = true;
1832       break;
1833 #endif
1834    case STREAM_XATTR_SOLARIS:
1835       if (pathconf(jcr->last_fname, _PC_XATTR_ENABLED) <= 0) {
1836          Qmsg1(jcr, M_WARNING, 0,
1837                _("Failed to restore extended attributes on file \"%s\"\n"),
1838                jcr->last_fname);
1839          Dmsg1(100, "Unable to restore extended attributes on file \"%s\", filesystem doesn't support this\n",
1840             jcr->last_fname);
1841          return bxattr_exit_error;
1842       }
1843       break;
1844    default:
1845       return bxattr_exit_error;
1846    }
1847
1848    /*
1849     * As we change the cwd in the restore function save the current cwd
1850     * for restore after return from the solaris_restore_xattrs function.
1851     */
1852    getcwd(cwd, sizeof(cwd));
1853    retval = solaris_restore_xattrs(jcr, is_extensible);
1854    chdir(cwd);
1855    return retval;
1856 }
1857
1858
1859 /*
1860  * Function pointers to the build and parse function to use for these xattrs.
1861  */
1862 static bxattr_exit_code (*os_build_xattr_streams)(JCR *jcr, FF_PKT *ff_pkt) = solaris_build_xattr_streams;
1863 static bxattr_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = solaris_parse_xattr_streams;
1864
1865 #endif /* defined(HAVE_SUN_OS) */
1866
1867 /*
1868  * Entry points when compiled with support for XATTRs on a supported platform.
1869  */
1870 bxattr_exit_code build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
1871 {
1872    if (os_build_xattr_streams) {
1873       return (*os_build_xattr_streams)(jcr, ff_pkt);
1874    }
1875    return bxattr_exit_error;
1876 }
1877
1878 bxattr_exit_code parse_xattr_streams(JCR *jcr, int stream)
1879 {
1880    unsigned int cnt;
1881
1882    if (os_parse_xattr_streams) {
1883       /*
1884        * See if we can parse this stream, and ifso give it a try.
1885        */
1886       for (cnt = 0; cnt < sizeof(os_default_xattr_streams) / sizeof(int); cnt++) {
1887          if (os_default_xattr_streams[cnt] == stream) {
1888             return (*os_parse_xattr_streams)(jcr, stream);
1889          }
1890       }
1891    }
1892    /*
1893     * Issue a warning and discard the message. But pretend the restore was ok.
1894     */
1895    Jmsg2(jcr, M_WARNING, 0,
1896       _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
1897       jcr->last_fname, stream);
1898    return bxattr_exit_error;
1899 }
1900 #endif