1 /*
2 Bacula(R) - The Network Backup Solution
3
4 Copyright (C) 2000-2020 Kern Sibbald
5
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
8
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
13
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
16
17 Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /**
20 * Major refactoring of ACL code written by:
21 *
22 * Radosław Korzeniewski, MMXVI
23 * radoslaw@korzeniewski.net, radekk@inteos.pl
24 * Inteos Sp. z o.o. http://www.inteos.pl/
25 *
26 *
27 * A specialized class to handle ACL in Bacula Enterprise.
28 * The runtime consist of two parts:
29 * 1. OS independent class: BACL
30 * 2. OS dependent subclass: BACL_*
31 *
32 * OS dependent subclasses are available for the following OS:
33 * - Darwin (OSX)
34 * - FreeBSD (POSIX and NFSv4/ZFS acls)
35 * - Linux
36 * - Solaris (POSIX and NFSv4/ZFS acls)
37 *
38 * OS dependent subclasses in progress:
39 * - AIX (pre-5.3 and post 5.3 acls, acl_get and aclx_get interface)
40 * - HPUX
41 * - IRIX
42 * - Tru64
43 *
44 * OS independent class support AFS acls using the pioctl interface.
45 *
46 * ACLs are saved in OS native text format provided by acl(3) API and uses
47 * different streams for all different platforms.
48 * Above behavior is a backward compatibility with previous Bacula implementation
49 * we need to maintain.
50 *
51 * During OS specific implementation of BACL you need to implement a following methods:
52 *
53 * [bacl] - indicates bacl function/method to call
54 * [os] - indicates OS specific function, which could be different on specific OS
55 * (we use a Linux API calls as an example)
56 *
57 * ::os_get_acl(JCR *jcr, BACL_type bacltype)
58 *
59 * 1. get binary form of the acl - acl_get_file[os]
60 * 2. check if acl is trivial if required - call acl_issimple[bacl]
61 * 3. translate binary form into text representation - acl_to_text[os]
62 * 4. save acl text into content - set_content[bacl]
63 * 5. if acl not supported on filesystem - call clear_flag(BACL_FLAG_NATIVE)[bacl]
64 *
65 * ::os_backup_acl (JCR *jcr, FF_PKT *ff_pkt)
66 *
67 * 1. call os_get_acl[bacl] for all supported ACL_TYPES
68 * 2. call send_acl_stream[bacl] for all supported ACL_STREAMS
69 *
70 * ::os_set_acl(JCR *jcr, BACL_type bacltype, char *content, uint32_t length)
71 *
72 * 1. prepare acl binary form from text representation stored in content - acl_from_text[os]
73 * 2. set acl on file - acl_set_file[os]
74 * 3. if acl not supported on filesystem, clear_flag(BACL_FLAG_NATIVE)
75 *
76 * ::os_restore_acl (JCR *jcr, int stream, char *content, uint32_t length)
77 *
78 * 1. call os_set_acl for all supported ACL_TYPES
79 */
80
81 #include "bacula.h"
82 #include "filed.h"
83 #include "fd_plugins.h"
84
85 /* check if ACL support is enabled */
86 #if defined(HAVE_ACL)
87
88 /*
89 * This is a constructor of the base BACL class which is OS independent
90 *
91 * - for initialization it uses ::init()
92 *
93 */
BACL()94 BACL::BACL (){
95 init();
96 };
97
98 /*
99 * This is a destructor of the BACL class
100 */
~BACL()101 BACL::~BACL (){
102 free_pool_memory(content);
103 };
104
105 /*
106 * Initialization routine
107 * - initializes all variables to required status
108 * - allocates required memory
109 */
init()110 void BACL::init(){
111 #if defined(HAVE_ACL)
112 acl_ena = TRUE;
113 #else
114 acl_ena = FALSE;
115 #endif
116
117 /* generic variables */
118 flags = BACL_FLAG_NONE;
119 current_dev = 0;
120 content = get_pool_memory(PM_BSOCK); /* it is better to have a 4k buffer */
121 content_len = 0;
122 acl_nr_errors = 0;
123 acl_streams = NULL;
124 default_acl_streams = NULL;
125 };
126
127 /*
128 * Enables ACL handling in runtime, could be disabled with disable_acl
129 * when ACL is not configured then cannot change status
130 */
enable_acl()131 void BACL::enable_acl(){
132 #if defined(HAVE_ACL)
133 acl_ena = TRUE;
134 #endif
135 };
136
137 /*
138 * Disables ACL handling in runtime, could be enabled with enable_acl
139 * when ACL is configured
140 */
disable_acl()141 void BACL::disable_acl(){
142 acl_ena = FALSE;
143 };
144
145 /*
146 * Copies a text into a content variable and sets a content_len respectively
147 *
148 * in:
149 * text - a standard null terminated string
150 * out:
151 * pointer to content variable to use externally
152 */
set_content(char * text)153 POOLMEM * BACL::set_content(char *text){
154 content_len = pm_strcpy(&content, text);
155 if (content_len > 0){
156 /* count the nul terminated char */
157 content_len++;
158 }
159 // Dmsg2(400, "BACL::set_content: %p %i\n", text, content_len);
160 return content;
161 };
162
163 /*
164 * Copies a data with length of len into a content variable
165 *
166 * in:
167 * data - data pointer to copy into content buffer
168 * out:
169 * pointer to content variable to use externally
170 */
set_content(char * data,int len)171 POOLMEM * BACL::set_content(char *data, int len){
172 content_len = pm_memcpy(&content, data, len);
173 return content;
174 };
175
176 /*
177 * Check if we changed the device,
178 * if so setup a flags
179 *
180 * in:
181 * jcr - Job Control Record
182 * out:
183 * bRC_BACL_ok - change of device checked and finish successful
184 * bRC_BACL_error - encountered error
185 * bRC_BACL_skip - cannot verify device - no file found
186 * bRC_BACL_inval - invalid input data
187 */
check_dev(JCR * jcr)188 bRC_BACL BACL::check_dev (JCR *jcr){
189
190 int lst;
191 struct stat st;
192
193 /* sanity check of input variables */
194 if (jcr == NULL || jcr->last_fname == NULL){
195 return bRC_BACL_inval;
196 }
197
198 lst = lstat(jcr->last_fname, &st);
199 switch (lst){
200 case -1: {
201 berrno be;
202 switch (errno){
203 case ENOENT:
204 return bRC_BACL_skip;
205 default:
206 Mmsg2(jcr->errmsg, _("Unable to stat file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror());
207 Dmsg2(100, "Unable to stat file \"%s\": ERR=%s\n", jcr->last_fname, be.bstrerror());
208 return bRC_BACL_error;
209 }
210 break;
211 }
212 case 0:
213 break;
214 }
215
216 check_dev(jcr, st.st_dev);
217
218 return bRC_BACL_ok;
219 };
220
221 /*
222 * Check if we changed the device, if so setup a flags
223 *
224 * in:
225 * jcr - Job Control Record
226 * out:
227 * internal flags status set
228 */
check_dev(JCR * jcr,uint32_t dev)229 void BACL::check_dev (JCR *jcr, uint32_t dev){
230
231 /* sanity check of input variables */
232 if (jcr == NULL || jcr->last_fname == NULL){
233 return;
234 }
235
236 if (current_dev != dev){
237 flags = BACL_FLAG_NONE;
238 #if defined(HAVE_AFS_ACL)
239 /* handle special fs: AFS */
240 if (fstype_equals(jcr->last_fname, "afs")){
241 set_flag(BACL_FLAG_AFS);
242 } else {
243 set_flag(BACL_FLAG_NATIVE);
244 }
245 #else
246 set_flag(BACL_FLAG_NATIVE);
247 #endif
248 current_dev = dev;
249 }
250 };
251
252 /*
253 * It sends a stream located in this->content to Storage Daemon, so the main Bacula
254 * backup loop is free from this. It sends a header followed by data.
255 *
256 * in:
257 * jcr - Job Control Record
258 * stream - a stream number to save
259 * out:
260 * bRC_BACL_inval - when supplied variables are incorrect
261 * bRC_BACL_fatal - when we can't send data to the SD
262 * bRC_BACL_ok - send finish without errors
263 */
send_acl_stream(JCR * jcr,int stream)264 bRC_BACL BACL::send_acl_stream(JCR *jcr, int stream){
265
266 BSOCK * sd;
267 POOLMEM * msgsave;
268 #ifdef FD_NO_SEND_TEST
269 return bRC_BACL_ok;
270 #endif
271
272 /* sanity check of input variables */
273 if (jcr == NULL || jcr->store_bsock == NULL){
274 return bRC_BACL_inval;
275 }
276 if (content_len <= 0){
277 return bRC_BACL_ok;
278 }
279
280 sd = jcr->store_bsock;
281 /* send header */
282 if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)){
283 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror());
284 return bRC_BACL_fatal;
285 }
286
287 /* send the buffer to the storage daemon */
288 Dmsg1(400, "Backing up ACL: %i\n", content_len);
289 #if 0
290 POOL_MEM tmp(PM_FNAME);
291 pm_memcpy(tmp, content, content_len);
292 Dmsg2(400, "Backing up ACL: (%i) <%s>\n", strlen(tmp.addr()), tmp.c_str());
293 #endif
294 msgsave = sd->msg;
295 sd->msg = content;
296 sd->msglen = content_len;
297 if (!sd->send()){
298 sd->msg = msgsave;
299 sd->msglen = 0;
300 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror());
301 return bRC_BACL_fatal;
302 }
303
304 jcr->JobBytes += sd->msglen;
305 sd->msg = msgsave;
306 if (!sd->signal(BNET_EOD)){
307 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror());
308 return bRC_BACL_fatal;
309 }
310
311 Dmsg1(200, "ACL of file: %s successfully backed up!\n", jcr->last_fname);
312 return bRC_BACL_ok;
313 };
314
315 /*
316 * The main public backup method for ACL
317 *
318 * in:
319 * jcr - Job Control Record
320 * ff_pkt - file backup record
321 * out:
322 * bRC_BACL_fatal - when ACL backup is not compiled in Bacula
323 * bRC_BACL_ok - backup finish without problems
324 * bRC_BACL_error - when you can't backup acl data because some error
325 */
backup_acl(JCR * jcr,FF_PKT * ff_pkt)326 bRC_BACL BACL::backup_acl (JCR *jcr, FF_PKT *ff_pkt)
327 {
328 #if !defined(HAVE_ACL) && !defined(HAVE_AFS_ACL)
329 Jmsg(jcr, M_FATAL, 0, "ACL backup requested but not configured in Bacula.\n");
330 return bRC_BACL_fatal;
331 #else
332 /* sanity check of input variables and verify if engine is enabled */
333 if (acl_ena && jcr != NULL && ff_pkt != NULL){
334 /* acl engine enabled, proceed */
335 bRC_BACL rc;
336
337 jcr->errmsg[0] = 0;
338 /* check if we have a plugin generated backup */
339 if (ff_pkt->cmd_plugin){
340 rc = backup_plugin_acl(jcr, ff_pkt);
341 } else {
342 /* Check for aclsupport flag and no acl request for link */
343 if (!(ff_pkt->flags & FO_ACL && ff_pkt->type != FT_LNK)){
344 return bRC_BACL_ok;
345 }
346
347 check_dev(jcr, ff_pkt->statp.st_dev);
348
349 #if defined(HAVE_AFS_ACL)
350 if (flags & BACL_FLAG_AFS){
351 Dmsg0(400, "make AFS ACL call\n");
352 rc = afs_backup_acl(jcr, ff_pkt);
353 goto bail_out;
354 }
355 #endif
356
357 #if defined(HAVE_ACL)
358 if (flags & BACL_FLAG_NATIVE){
359 Dmsg0(400, "make Native ACL call\n");
360 rc = os_backup_acl(jcr, ff_pkt);
361 } else {
362 /* skip acl backup */
363 return bRC_BACL_ok;
364 }
365 #endif
366 }
367 #if defined(HAVE_AFS_ACL)
368 bail_out:
369 #endif
370 if (rc == bRC_BACL_error){
371 if (acl_nr_errors < ACL_MAX_ERROR_PRINT_PER_JOB){
372 if (!jcr->errmsg[0]){
373 Jmsg(jcr, M_WARNING, 0, "No OS ACL configured.\n");
374 } else {
375 Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
376 }
377 inc_acl_errors();
378 }
379 return bRC_BACL_ok;
380 }
381 return rc;
382 }
383 return bRC_BACL_ok;
384 #endif
385 };
386
387 /*
388 * The main public restore method for ACL
389 *
390 * in:
391 * jcr - Job Control Record
392 * stream - a backup stream type number to restore_acl
393 * data - a pointer to the data stream to restore
394 * length - a data stream length
395 * out:
396 * bRC_BACL_fatal - when ACL restore is not compiled in Bacula
397 * bRC_BACL_ok - restore finish without problems
398 * bRC_BACL_error - when you can't restore a stream because some error
399 */
restore_acl(JCR * jcr,int stream,char * data,uint32_t length)400 bRC_BACL BACL::restore_acl (JCR *jcr, int stream, char *data, uint32_t length)
401 {
402 #if !defined(HAVE_ACL) && !defined(HAVE_AFS_ACL)
403 Jmsg(jcr, M_FATAL, 0, "ACL restore requested but not configured in Bacula.\n");
404 return bRC_BACL_fatal;
405 #else
406 /* sanity check of input variables and verify if engine is enabled */
407 if (acl_ena && jcr != NULL && data != NULL){
408 /* acl engine enabled, proceed */
409 int a;
410 bRC_BACL rc;
411
412 /* check_dev supported on real fs only */
413 if (stream != STREAM_XACL_PLUGIN_ACL){
414 rc = check_dev(jcr);
415
416 switch (rc){
417 case bRC_BACL_skip:
418 return bRC_BACL_ok;
419 case bRC_BACL_ok:
420 break;
421 default:
422 return rc;
423 }
424 }
425
426 /* copy a data into a content buffer */
427 set_content(data, length);
428
429 switch (stream){
430 #if defined(HAVE_AFS_ACL)
431 case STREAM_BACL_AFS_TEXT:
432 if (flags & BACL_FLAG_AFS){
433 return afs_restore_acl(jcr, stream);
434 } else {
435 /*
436 * Increment error count but don't log an error again for the same filesystem.
437 */
438 inc_acl_errors();
439 return bRC_BACL_ok;
440 }
441 #endif
442 #if defined(HAVE_ACL)
443 case STREAM_UNIX_ACCESS_ACL:
444 case STREAM_UNIX_DEFAULT_ACL:
445 if (flags & BACL_FLAG_NATIVE){
446 return os_restore_acl(jcr, stream, content, content_len);
447 } else {
448 inc_acl_errors();
449 return bRC_BACL_ok;
450 }
451 break;
452 case STREAM_XACL_PLUGIN_ACL:
453 return restore_plugin_acl(jcr);
454 default:
455 if (flags & BACL_FLAG_NATIVE){
456 Dmsg0(400, "make Native ACL call\n");
457 for (a = 0; acl_streams[a] > 0; a++){
458 if (acl_streams[a] == stream){
459 return os_restore_acl(jcr, stream, content, content_len);
460 }
461 }
462 for (a = 0; default_acl_streams[a] > 0; a++){
463 if (default_acl_streams[a] == stream){
464 return os_restore_acl(jcr, stream, content, content_len);
465 }
466 }
467 } else {
468 inc_acl_errors();
469 return bRC_BACL_ok;
470 }
471 break;
472 #else
473 default:
474 break;
475 #endif
476 }
477 /* cannot find a valid stream to support */
478 Qmsg2(jcr, M_WARNING, 0, _("Can't restore ACLs of %s - incompatible acl stream encountered - %d\n"), jcr->last_fname, stream);
479 return bRC_BACL_error;
480 }
481 return bRC_BACL_ok;
482 #endif
483 };
484
485 /*
486 * Performs a generic ACL backup using OS specific methods for
487 * getting acl data from file
488 *
489 * in:
490 * jcr - Job Control Record
491 * ff_pkt - file to backup control package
492 * out:
493 * bRC_BACL_ok - backup of acl's was successful
494 * bRC_BACL_fatal - was an error during acl backup
495 */
generic_backup_acl(JCR * jcr,FF_PKT * ff_pkt)496 bRC_BACL BACL::generic_backup_acl (JCR *jcr, FF_PKT *ff_pkt)
497 {
498 /* sanity check of input variables */
499 if (jcr == NULL || ff_pkt == NULL){
500 return bRC_BACL_inval;
501 }
502
503 if (os_get_acl(jcr, BACL_TYPE_ACCESS) == bRC_BACL_fatal){
504 /* XXX: check if os_get_acl return fatal and decide what to do when error is returned */
505 return bRC_BACL_fatal;
506 }
507
508 if (content_len > 0){
509 if (send_acl_stream(jcr, acl_streams[0]) == bRC_BACL_fatal){
510 return bRC_BACL_fatal;
511 }
512 }
513
514 if (ff_pkt->type == FT_DIREND){
515 if (os_get_acl(jcr, BACL_TYPE_DEFAULT) == bRC_BACL_fatal){
516 return bRC_BACL_fatal;
517 }
518 if (content_len > 0){
519 if (send_acl_stream(jcr, default_acl_streams[0]) == bRC_BACL_fatal){
520 return bRC_BACL_fatal;
521 }
522 }
523 }
524 return bRC_BACL_ok;
525 };
526
527 /*
528 * Performs a generic ACL restore using OS specific methods for
529 * setting acl data on file.
530 *
531 * in:
532 * jcr - Job Control Record
533 * stream - a stream number to restore
534 * out:
535 * bRC_BACL_ok - restore of acl's was successful
536 * bRC_BACL_error - was an error during acl restore
537 * bRC_BACL_fatal - was a fatal error during acl restore or input data
538 * is invalid
539 */
generic_restore_acl(JCR * jcr,int stream)540 bRC_BACL BACL::generic_restore_acl (JCR *jcr, int stream){
541
542 unsigned int count;
543
544 /* sanity check of input variables */
545 if (jcr == NULL){
546 return bRC_BACL_inval;
547 }
548
549 switch (stream){
550 case STREAM_UNIX_ACCESS_ACL:
551 return os_set_acl(jcr, BACL_TYPE_ACCESS, content, content_len);
552 case STREAM_UNIX_DEFAULT_ACL:
553 return os_set_acl(jcr, BACL_TYPE_DEFAULT, content, content_len);
554 default:
555 for (count = 0; acl_streams[count] > 0; count++){
556 if (acl_streams[count] == stream){
557 return os_set_acl(jcr, BACL_TYPE_ACCESS, content, content_len);
558 }
559 }
560 for (count = 0; default_acl_streams[count] > 0; count++){
561 if (default_acl_streams[count] == stream){
562 return os_set_acl(jcr, BACL_TYPE_DEFAULT, content, content_len);
563 }
564 }
565 break;
566 }
567 return bRC_BACL_error;
568 };
569
570 /*
571 * Perform a generic ACL backup using a plugin. It calls the plugin API to
572 * get required acl data from plugin.
573 *
574 * in:
575 * jcr - Job Control Record
576 * ff_pkt - file to backup control package
577 * out:
578 * bRC_BACL_ok - backup of acls was successful
579 * bRC_BACL_fatal - was an error during acl backup
580 */
backup_plugin_acl(JCR * jcr,FF_PKT * ff_pkt)581 bRC_BACL BACL::backup_plugin_acl (JCR *jcr, FF_PKT *ff_pkt)
582 {
583 int status;
584 char *data;
585
586 /* sanity check of input variables */
587 if (jcr == NULL || ff_pkt == NULL){
588 return bRC_BACL_inval;
589 }
590
591 while ((status = plugin_backup_acl(jcr, ff_pkt, &data)) > 0){
592 /* data is a plugin buffer which contains data to backup
593 * and status is a length of the buffer when > 0 */
594 set_content(data, status);
595 if (send_acl_stream(jcr, STREAM_XACL_PLUGIN_ACL) == bRC_BACL_fatal){
596 return bRC_BACL_fatal;
597 }
598 }
599 if (status < 0){
600 /* error */
601 return bRC_BACL_error;
602 }
603
604 return bRC_BACL_ok;
605 };
606
607 /*
608 * Perform a generic ACL restore using a plugin. It calls the plugin API to
609 * send acl data to plugin.
610 *
611 * in:
612 * jcr - Job Control Record
613 * stream - a stream number to restore
614 * out:
615 * bRC_BACL_ok - restore of acls was successful
616 * bRC_BACL_error - was an error during acls restore
617 * bRC_BACL_fatal - was a fatal error during acl restore or input data
618 * is invalid
619 */
restore_plugin_acl(JCR * jcr)620 bRC_BACL BACL::restore_plugin_acl (JCR *jcr)
621 {
622 /* sanity check of input variables */
623 if (jcr == NULL){
624 return bRC_BACL_inval;
625 }
626
627 if (!plugin_restore_acl(jcr, content, content_len)){
628 /* error */
629 return bRC_BACL_error;
630 }
631
632 return bRC_BACL_ok;
633 }
634
635 /*
636 * Initialize variables acl_streams and default_acl_streams for a specified OS.
637 * The rutine should be called from object instance constructor
638 *
639 * in:
640 * pacl - acl streams supported for specific OS
641 * pacl_def - default (directory) acl streams supported for specific OS
642 */
set_acl_streams(const int * pacl,const int * pacl_def)643 void BACL::set_acl_streams (const int *pacl, const int *pacl_def){
644
645 acl_streams = pacl;
646 default_acl_streams = pacl_def;
647 };
648
649 #if defined(HAVE_AFS_ACL)
650 #if defined(HAVE_AFS_AFSINT_H) && defined(HAVE_AFS_VENUS_H)
651 #include <afs/afsint.h>
652 #include <afs/venus.h>
653 #else
654 #error "configure failed to detect availability of afs/afsint.h and/or afs/venus.h"
655 #endif
656
657 /*
658 * External references to functions in the libsys library function not in current include files.
659 */
660 extern "C" {
661 long pioctl(char *pathp, long opcode, struct ViceIoctl *blobp, int follow);
662 }
663
664 /*
665 * Backup ACL data of AFS
666 *
667 * in:
668 * jcr - Job Control Record
669 * ff_pkt - file backup record
670 * out:
671 * bRC_BACL_inval - input variables are invalid (NULL)
672 * bRC_BACL_ok - backup finish without problems
673 * bRC_BACL_error - when you can't backup acl data because some error
674 */
afs_backup_acl(JCR * jcr,FF_PKT * ff_pkt)675 bRC_BACL BACL::afs_backup_acl (JCR *jcr, FF_PKT *ff_pkt){
676
677 int rc;
678 struct ViceIoctl vip;
679 char data[BUFSIZ];
680
681 /* sanity check of input variables */
682 if (jcr == NULL || ff_pkt == NULL){
683 return bRC_BACL_inval;
684 }
685
686 /* AFS ACLs can only be set on a directory, so no need to try other files */
687 if (ff_pkt->type != FT_DIREND){
688 return bRC_BACL_ok;
689 }
690
691 vip.in = NULL;
692 vip.in_size = 0;
693 vip.out = data;
694 vip.out_size = BUFSIZE;
695 memset(data, 0, BUFSIZE);
696
697 if ((rc = pioctl(jcr->last_fname, VIOCGETAL, &vip, 0)) < 0){
698 berrno be;
699
700 Mmsg2(jcr->errmsg, _("pioctl VIOCGETAL error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror());
701 Dmsg2(100, "pioctl VIOCGETAL error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror());
702 return bRC_BACL_error;
703 }
704 set_content(data);
705 return send_acl_stream(jcr, STREAM_BACL_AFS_TEXT);
706 };
707
708 /*
709 * Restore ACL data of AFS
710 * in:
711 * jcr - Job Control Record
712 * stream - a backup stream type number to restore_acl
713 * out:
714 * bRC_BACL_inval - input variables are invalid (NULL)
715 * bRC_BACL_ok - backup finish without problems
716 * bRC_BACL_error - when you can't backup acl data because some error
717 */
afs_restore_acl(JCR * jcr,int stream)718 bRC_BACL BACL::afs_restore_acl (JCR *jcr, int stream){
719
720 int rc;
721 struct ViceIoctl vip;
722
723 /* sanity check of input variables */
724 if (jcr == NULL || ff_pkt == NULL){
725 return bRC_BACL_inval;
726 }
727
728 vip.in = content;
729 vip.in_size = content_len;
730 vip.out = NULL;
731 vip.out_size = 0;
732
733 if ((rc = pioctl(jcr->last_fname, VIOCSETAL, &vip, 0)) < 0){
734 berrno be;
735
736 Mmsg2(jcr->errmsg, _("pioctl VIOCSETAL error on file \"%s\": ERR=%s\n"), jcr->last_fname, be.bstrerror());
737 Dmsg2(100, "pioctl VIOCSETAL error file=%s ERR=%s\n", jcr->last_fname, be.bstrerror());
738
739 return bRC_BACL_error;
740 }
741 return bRC_BACL_ok;
742 };
743 #endif /* HAVE_AFS_ACL */
744
745 #include "bacl_osx.h"
746 #include "bacl_linux.h"
747 #include "bacl_freebsd.h"
748 #include "bacl_solaris.h"
749 // #include "bacl_aix.h"
750
751 /*
752 * Creating the correct instance of the BACL for a supported OS
753 */
new_bacl()754 void *new_bacl()
755 {
756 #if defined(HAVE_DARWIN_OS)
757 return new BACL_OSX();
758 #elif defined(HAVE_LINUX_OS)
759 return new BACL_Linux();
760 #elif defined(HAVE_FREEBSD_OS)
761 return new BACL_FreeBSD();
762 #elif defined(HAVE_HURD_OS)
763 return new BACL_Hurd();
764 #elif defined(HAVE_AIX_OS)
765 return new BACL_AIX();
766 #elif defined(HAVE_IRIX_OS)
767 return new BACL_IRIX();
768 #elif defined(HAVE_OSF1_OS)
769 return new BACL_OSF1();
770 #elif defined(HAVE_SUN_OS)
771 return new BACL_Solaris();
772 #else
773 return NULL;
774 #endif
775 };
776
777 #endif /* HAVE_ACL */
778