From: Kern Sibbald Date: Wed, 12 Jan 2005 09:41:23 +0000 (+0000) Subject: Integrate Preben 'Peppe' Guldberg 's X-Git-Tag: Release-1.38.0~664 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=d560095a76e38391cfed3090866c6192e926a85e;p=bacula%2Fbacula Integrate Preben 'Peppe' Guldberg 's acl patch. Fix case where configured but no ACL exists. Rework calling arguments to be shorter and positioned more typically in Bacula usage. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1800 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/src/filed/acl.c b/bacula/src/filed/acl.c index 6cd35e7d79..2e5a85a692 100644 --- a/bacula/src/filed/acl.c +++ b/bacula/src/filed/acl.c @@ -29,15 +29,6 @@ * Version $Id$ */ -#ifdef xxxxxxx - -Remove fprintf() and actuallyfree and fix POOLMEM coding - -Pass errmsg buffer and a length or a POOLMEM buffer -into subroutine rather than malloc in -subroutine and free() in higher level routine, which causes -memory leaks if you forget to free. - #ifndef TEST_PROGRAM #include "bacula.h" @@ -66,11 +57,21 @@ memory leaks if you forget to free. #include #include "acl.h" -#define POOLMEM char -#define bstrdup strdup +#define BACLLEN 65535 +#define pm_strcpy(d,s) (strncpy(d, s, BACLLEN - 1) == NULL ? -1 : (int)strlen(d)) +#define Dmsg0(n,s) fprintf(stderr, s) +#define Dmsg1(n,s,a1) fprintf(stderr, s, a1) +#define Dmsg2(n,s,a1,a2) fprintf(stderr, s, a1, a2) + int aclls(char *fname); int aclcp(char *src, char *dst); +struct JCRstruct { + char *last_fname; + char acl_text[BACLLEN]; +}; +typedef struct JCRstruct JCR; +JCR jcr; #endif /* @@ -87,13 +88,24 @@ int aclcp(char *src, char *dst); || defined(HAVE_HPUX_OS) /* man page -- may need flags */ \ || defined(HAVE_SUN_OS) /* tested -- compile with -lsec */ \ ) +/* + * ***FIXME*** + * For now we abandon this test and only test for Linux: + * 1. This is backwards compatible. + * 2. If we allow any of the other now, we may have to provide conversion + * routines if we ever want to distinguish them. Or just do our best + * with what we have and give all ACL streams a new number/type. + */ +#endif +#if !defined(HAVE_ACL) || ! defined(HAVE_LINUX_OS) -POOLMEM *bacl_get(char *fname, int acltype) +/* bacl_get() returns the lenght of the string, or -1 on error. */ +int bacl_get(JCR *jcr, int acltype) { - return NULL; + return -1; } -int bacl_set(char *fname, int acltype, char *acltext) +int bacl_set(JCR *jcr, int acltype) { return -1; } @@ -102,21 +114,22 @@ int bacl_set(char *fname, int acltype, char *acltext) #include -bool bacl_get(JCR *jcr, char *fname, int acltype) +int bacl_get(JCR *jcr, int acltype) { char *acl_text; + int len; - if ((acl_text = acl_get(fname)) != NULL) { - pm_strcpy(jcr->acl_text, acl_text); + if ((acl_text = acl_get(jcr->last_fname)) != NULL) { + len = pm_strcpy(jcr->acl_text, acl_text); free(acl_text); - return true; + return len; } - return false; + return -1; } -int bacl_set(char *fname, int acltype, char *acltext) +int bacl_set(JCR *jcr, int acltype) { - if (acl_put(fname, acltext, 0) != 0) { + if (acl_put(jcr->last_fname, jcr->acl_text, 0) != 0) { return -1; } return 0; @@ -150,36 +163,43 @@ int bacl_set(char *fname, int acltype, char *acltext) #endif #endif -bool bacl_get(JCR *jcr, char *fname, int acltype) +int bacl_get(JCR *jcr, int acltype) { acl_t acl; - int ostype; + int len, ostype; char *acl_text; ostype = (acltype & BACL_TYPE_DEFAULT) ? ACL_TYPE_DEFAULT : ACL_TYPE_ACCESS; - acl = acl_get_file(fname, ostype); + acl = acl_get_file(jcr->last_fname, ostype); if (acl) { if ((acl_text = acl_to_text(acl, NULL)) != NULL) { - pm_strcpy(jcr->acl_text, acl_text); + len = pm_strcpy(jcr->acl_text, acl_text); acl_free(acl_text); - return true; + return len; } - acl_free(acl_text); } /***** Do we really want to silently ignore errors from acl_get_file and acl_to_text? *****/ - return false; + return -1; } -int bacl_set(char *fname, int acltype, char *acltext) +int bacl_set(JCR *jcr, int acltype) { acl_t acl; - int ostype, stat; + int ostype; ostype = (acltype & BACL_TYPE_DEFAULT) ? ACL_TYPE_DEFAULT : ACL_TYPE_ACCESS; - acl = acl_from_text(acltext); + /* If we get empty default ACLs, clear ACLs now */ + if (ostype == ACL_TYPE_DEFAULT && strlen(jcr->acl_text) == 0) { + if (acl_delete_def_file(jcr->last_fname) == 0) { + return 0; + } + return -1; + } + + acl = acl_from_text(jcr->acl_text); if (acl == NULL) { return -1; } @@ -195,47 +215,50 @@ int bacl_set(char *fname, int acltype, char *acltext) } #endif - stat = acl_set_file(fname, ostype, acl); + if (acl_set_file(jcr->last_fname, ostype, acl) != 0) { + acl_free(acl); + return -1; + } acl_free(acl); - return stat; + return 0; } #elif defined(HAVE_HPUX_OS) #include #include -POOLMEM *bacl_get(char *fname, int acltype) +int bacl_get(JCR *jcr, int acltype) { - int n; + int n, len; struct acl_entry acls[NACLENTRIES]; - char *tmp; - POOLMEM *acltext = NULL; + char *acl_text; - if ((n = getacl(fname, 0, acls)) <= 0) { - return NULL; + if ((n = getacl(jcr->last_fname, 0, acls)) <= 0) { + return -1; } - if ((n = getacl(fname, n, acls)) > 0) { - if ((tmp = acltostr(n, acls, FORM_SHORT)) != NULL) { - acltext = bstrdup(tmp); - actuallyfree(tmp); + if ((n = getacl(jcr->last_fname, n, acls)) > 0) { + if ((acl_text = acltostr(n, acls, FORM_SHORT)) != NULL) { + len = pm_strcpy(jcr->acl_text, acl_text); + free(acl_text); + return len; } } - return acltext; + return -1; } -int bacl_set(char *fname, int acltype, char *acltext) +int bacl_set(JCR *jcr, int acltype) { int n, stat; struct acl_entry acls[NACLENTRIES]; - n = strtoacl(acltext, 0, NACLENTRIES, acls, ACL_FILEOWNER, ACL_FILEGROUP); + n = strtoacl(jcr->acl_text, 0, NACLENTRIES, acls, ACL_FILEOWNER, ACL_FILEGROUP); if (n <= 0) { return -1; } - if (strtoacl(acltext, n, NACLENTRIES, acls, ACL_FILEOWNER, ACL_FILEGROUP) != n) { + if (strtoacl(jcr->acl_text, n, NACLENTRIES, acls, ACL_FILEOWNER, ACL_FILEGROUP) != n) { return -1; } - if (setacl(fname, n, acls) != 0) { + if (setacl(jcr->last_fname, n, acls) != 0) { return -1; } return 0; @@ -244,42 +267,46 @@ int bacl_set(char *fname, int acltype, char *acltext) #elif defined(HAVE_SUN_OS) #include -POOLMEM *bacl_get(char *fname, int acltype) +int bacl_get(JCR *jcr, int acltype) { - int n; + int n, len; aclent_t *acls; - char *tmp; - POOLMEM *acltext = NULL; + char *acl_text; - n = acl(fname, GETACLCNT, 0, NULL); + n = acl(jcr->last_fname, GETACLCNT, 0, NULL); if (n <= 0) { - return NULL; + return -1; } if ((acls = (aclent_t *)malloc(n * sizeof(aclent_t))) == NULL) { - return NULL; + return -1; } - if (acl(fname, GETACL, n, acls) == n) { - if ((tmp = acltotext(acls, n)) != NULL) { - acltext = bstrdup(tmp); - actuallyfree(tmp); + if (acl(jcr->last_fname, GETACL, n, acls) == n) { + if ((acl_text = acltotext(acls, n)) != NULL) { + pm_strcpy(jcr->acl_text, acl_text); + free(acl_text); + free(acls); + return len; } } - actuallyfree(acls); - return acltext; + free(acls); + return -1; } -int bacl_set(char *fname, int acltype, char *acltext) +int bacl_set(JCR *jcr, int acltype) { - int n, stat; + int n; aclent_t *acls; - acls = aclfromtext(acltext, &n); + acls = aclfromtext(jcr->acl_text, &n); if (!acls) { return -1; } - stat = acl(fname, SETACL, n, acls); - actuallyfree(acls); - return stat; + if (acl(jcr->last_fname, SETACL, n, acls) != 0) { + free(acls); + return -1; + } + free(acls); + return 0; } #endif @@ -292,7 +319,7 @@ int main(int argc, char **argv) int status = 0; if (argc < 1) { - fprintf(stderr, "Cannot determine my own name\n"); + Dmsg0(200, "Cannot determine my own name\n"); return EXIT_FAILURE; } @@ -312,7 +339,7 @@ int main(int argc, char **argv) ++argv; } if (argc != 2) { - fprintf(stderr, "%s: wrong number of arguments\n" + Dmsg2(200, "%s: wrong number of arguments\n" "usage:\t%s [-v] source destination\n" "\tCopies ACLs from source to destination.\n" "\tSpecify -v to show ACLs after copy for verification.\n", @@ -320,7 +347,7 @@ int main(int argc, char **argv) return EXIT_FAILURE; } if (strcmp(argv[0], argv[1]) == 0) { - fprintf(stderr, "%s: identical source and destination.\n" + Dmsg2(200, "%s: identical source and destination.\n" "usage:\t%s [-v] source destination\n" "\tCopies ACLs from source to destination.\n" "\tSpecify -v to show ACLs after copy for verification.\n", @@ -339,7 +366,7 @@ int main(int argc, char **argv) /* Default: just list ACLs */ if (argc < 1) { - fprintf(stderr, "%s: missing arguments\n" + Dmsg2(200, "%s: missing arguments\n" "usage:\t%s file ...\n" "\tLists ACLs of specified files or directories.\n", prgname, prgname); @@ -358,47 +385,47 @@ int main(int argc, char **argv) int aclcp(char *src, char *dst) { struct stat st; - POOLMEM *acltext; if (lstat(dst, &st) != 0) { - fprintf(stderr, "aclcp: destination does not exist\n"); + Dmsg0(200, "aclcp: destination does not exist\n"); return EXIT_FAILURE; } if (S_ISLNK(st.st_mode)) { - fprintf(stderr, "aclcp: cannot set ACL on symlinks\n"); + Dmsg0(200, "aclcp: cannot set ACL on symlinks\n"); return EXIT_FAILURE; } if (lstat(src, &st) != 0) { - fprintf(stderr, "aclcp: source does not exist\n"); + Dmsg0(200, "aclcp: source does not exist\n"); return EXIT_FAILURE; } if (S_ISLNK(st.st_mode)) { - fprintf(stderr, "aclcp: will not read ACL from symlinks\n"); + Dmsg0(200, "aclcp: will not read ACL from symlinks\n"); return EXIT_FAILURE; } - acltext = bacl_get(src, BACL_TYPE_ACCESS); - if (!acltext) { - fprintf(stderr, "aclcp: could not read ACLs for %s\n", src); + jcr.last_fname = src; + if (bacl_get(&jcr, BACL_TYPE_ACCESS) < 0) { + Dmsg1(200, "aclcp: could not read ACLs for %s\n", jcr.last_fname); return EXIT_FAILURE; } else { - if (bacl_set(dst, BACL_TYPE_ACCESS, acltext) != 0) { - fprintf(stderr, "aclcp: could not set ACLs on %s\n", dst); - actuallyfree(acltext); + jcr.last_fname = dst; + if (bacl_set(&jcr, BACL_TYPE_ACCESS) < 0) { + Dmsg1(200, "aclcp: could not set ACLs on %s\n", jcr.last_fname); return EXIT_FAILURE; } - actuallyfree(acltext); } if (S_ISDIR(st.st_mode) && (BACL_CAP & BACL_CAP_DEFAULTS_DIR)) { - acltext = bacl_get(src, BACL_TYPE_DEFAULT); - if (acltext) { - if (bacl_set(dst, BACL_TYPE_DEFAULT, acltext) != 0) { - fprintf(stderr, "aclcp: could not set default ACLs on %s\n", dst); - actuallyfree(acltext); + jcr.last_fname = src; + if (bacl_get(&jcr, BACL_TYPE_DEFAULT) < 0) { + Dmsg1(200, "aclcp: could not read default ACLs for %s\n", jcr.last_fname); + return EXIT_FAILURE; + } else { + jcr.last_fname = dst; + if (bacl_set(&jcr, BACL_TYPE_DEFAULT) < 0) { + Dmsg1(200, "aclcp: could not set default ACLs on %s\n", jcr.last_fname); return EXIT_FAILURE; } - actuallyfree(acltext); } } @@ -409,36 +436,32 @@ int aclcp(char *src, char *dst) int aclls(char *fname) { struct stat st; - POOLMEM *acltext; if (lstat(fname, &st) != 0) { - fprintf(stderr, "acl: source does not exist\n"); + Dmsg0(200, "acl: source does not exist\n"); return EXIT_FAILURE; } if (S_ISLNK(st.st_mode)) { - fprintf(stderr, "acl: will not read ACL from symlinks\n"); + Dmsg0(200, "acl: will not read ACL from symlinks\n"); return EXIT_FAILURE; } - acltext = bacl_get(fname, BACL_TYPE_ACCESS); - if (!acltext) { - fprintf(stderr, "acl: could not read ACLs for %s\n", fname); + jcr.last_fname = fname; + + if (bacl_get(&jcr, BACL_TYPE_ACCESS) < 0) { + Dmsg1(200, "acl: could not read ACLs for %s\n", jcr.last_fname); return EXIT_FAILURE; } - printf("#file: %s\n%s\n", fname, acltext); - actuallyfree(acltext); + printf("#file: %s\n%s\n", jcr.last_fname, jcr.acl_text); if (S_ISDIR(st.st_mode) && (BACL_CAP & BACL_CAP_DEFAULTS_DIR)) { - acltext = bacl_get(fname, BACL_TYPE_DEFAULT); - if (!acltext) { - fprintf(stderr, "acl: could not read default ACLs for %s\n", fname); + if (bacl_get(&jcr, BACL_TYPE_DEFAULT) < 0) { + Dmsg1(200, "acl: could not read default ACLs for %s\n", jcr.last_fname); return EXIT_FAILURE; } - printf("#file: %s [default]\n%s\n", fname, acltext); - actuallyfree(acltext); + printf("#file: %s [default]\n%s\n", jcr.last_fname, jcr.acl_text); } return 0; } #endif -#endif diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index 9405ec0d24..1508cf8687 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -30,14 +30,12 @@ #include "bacula.h" #include "filed.h" +static int save_file(FF_PKT *ff_pkt, void *pkt); +static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, struct CHKSUM *chksum); #ifdef HAVE_ACL -#include -#include +static int read_and_send_acl(JCR *jcr, int acltype, int stream); #endif -static int save_file(FF_PKT *ff_pkt, void *pkt); -static int send_data(int stream, FF_PKT *ff_pkt, BSOCK *sd, JCR *jcr, struct CHKSUM *chksum); - /* * Find all the requested files and send them * to the Storage daemon. @@ -92,6 +90,8 @@ bool blast_data_to_storage_daemon(JCR *jcr, char *addr) start_heartbeat_monitor(jcr); + jcr->acl_text = get_pool_memory(PM_MESSAGE); + /* Subroutine save_file() is called for each file */ if (!find_files(jcr, (FF_PKT *)jcr->ff, save_file, (void *)jcr)) { ok = false; /* error */ @@ -99,6 +99,8 @@ bool blast_data_to_storage_daemon(JCR *jcr, char *addr) // Jmsg(jcr, M_FATAL, 0, _("Find files error.\n")); } + free_pool_memory(jcr->acl_text); + stop_heartbeat_monitor(jcr); bnet_sig(sd, BNET_EOD); /* end data connection */ @@ -117,8 +119,7 @@ bool blast_data_to_storage_daemon(JCR *jcr, char *addr) /* * Called here by find() for each file included. - * - * *****FIXME***** add FSMs File System Modules + * This is a callback. The original is find_files() above. * * Send the file and its data to the Storage daemon. * @@ -185,25 +186,22 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) break; case FT_NOACCESS: { berrno be; - be.set_errno(ff_pkt->ff_errno); Jmsg(jcr, M_NOTSAVED, 0, _(" Could not access %s: ERR=%s\n"), ff_pkt->fname, - be.strerror()); + be.strerror(ff_pkt->ff_errno)); jcr->Errors++; return 1; } case FT_NOFOLLOW: { berrno be; - be.set_errno(ff_pkt->ff_errno); Jmsg(jcr, M_NOTSAVED, 0, _(" Could not follow link %s: ERR=%s\n"), ff_pkt->fname, - be.strerror()); + be.strerror(ff_pkt->ff_errno)); jcr->Errors++; return 1; } case FT_NOSTAT: { berrno be; - be.set_errno(ff_pkt->ff_errno); Jmsg(jcr, M_NOTSAVED, 0, _(" Could not stat %s: ERR=%s\n"), ff_pkt->fname, - be.strerror()); + be.strerror(ff_pkt->ff_errno)); jcr->Errors++; return 1; } @@ -216,9 +214,8 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) return 1; case FT_NOOPEN: { berrno be; - be.set_errno(ff_pkt->ff_errno); Jmsg(jcr, M_NOTSAVED, 0, _(" Could not open directory %s: ERR=%s\n"), ff_pkt->fname, - be.strerror()); + be.strerror(ff_pkt->ff_errno)); jcr->Errors++; return 1; } @@ -250,7 +247,6 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) * */ if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, attr_stream)) { - berrno be; Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), bnet_strerror(sd)); return 0; @@ -285,7 +281,6 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg); if (!stat) { - berrno be; Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), bnet_strerror(sd)); return 0; @@ -338,7 +333,7 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) stop_thread_timer(tid); tid = NULL; } - stat = send_data(data_stream, ff_pkt, sd, jcr, &chksum); + stat = send_data(jcr, data_stream, ff_pkt, &chksum); bclose(&ff_pkt->bfd); if (!stat) { return 0; @@ -364,7 +359,7 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) } flags = ff_pkt->flags; ff_pkt->flags &= ~(FO_GZIP|FO_SPARSE); - stat = send_data(STREAM_MACOS_FORK_DATA, ff_pkt, sd, jcr, &chksum); + stat = send_data(jcr, STREAM_MACOS_FORK_DATA, ff_pkt, &chksum); ff_pkt->flags = flags; bclose(&ff_pkt->bfd); if (!stat) { @@ -384,113 +379,14 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) #endif #ifdef HAVE_ACL - /*** FIXME ***/ - /* ACL stream */ - if (ff_pkt->flags & FO_ACL) { - char *acl_text = NULL; - char *aclDef_text = NULL; - - /* Read ACLs for files, dirs and links */ - if (ff_pkt->type == FT_DIREND) { - /* Directory: Check for default ACL*/ - acl_t myDefAcl = acl_get_file(ff_pkt->fname, ACL_TYPE_DEFAULT); - /* Check for Access ACL */ - acl_t myAccAcl = acl_get_file(ff_pkt->fname, ACL_TYPE_ACCESS); - if (!myDefAcl || !myAccAcl) { - Jmsg1(jcr, M_WARNING, 0, "Error while trying to get ACL of directory: %s!\n", ff_pkt->fname); - } - if(myDefAcl){ - aclDef_text = acl_to_any_text(myDefAcl, NULL, ',', TEXT_ABBREVIATE); - acl_free(myDefAcl); - } - if(myAccAcl){ - acl_text = acl_to_any_text(myAccAcl, NULL, ',', TEXT_ABBREVIATE); - acl_free(myAccAcl); - } - } else { - /* Files or links */ - acl_t myAcl = acl_get_file(ff_pkt->fname, ACL_TYPE_ACCESS); - if (!myAcl) { - Jmsg1(jcr, M_WARNING, 0, "Error while trying to get ACL of file: %s!\n", ff_pkt->fname); - acl_free(myAcl); - } - acl_text = acl_to_any_text(myAcl, NULL, ',', TEXT_ABBREVIATE); - acl_free(myAcl); - } - - POOLMEM *msgsave; - - /* If there is an ACL, send it to the Storage daemon */ - if (acl_text != NULL) { - sd = jcr->store_bsock; - pm_strcpy(&jcr->last_fname, ff_pkt->fname); - - - // Send ACL header - if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES_ACCESS_ACL)) { - berrno be; - Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), - bnet_strerror(sd)); - return 0; - } - - /* Send the buffer to the storage deamon */ - msgsave = sd->msg; - sd->msg = acl_text; - sd->msglen = strlen(acl_text) + 1; - if (!bnet_send(sd)) { - berrno be; - sd->msg = msgsave; - sd->msglen = 0; - Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), - bnet_strerror(sd)); - } else { - jcr->JobBytes += sd->msglen; - sd->msg = msgsave; - if (!bnet_sig(sd, BNET_EOD)) { - berrno be; - Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), - bnet_strerror(sd)); - } else { - Dmsg1(200, "ACL of file: %s successfully backed up!\n", ff_pkt->fname); - } - } - } - /* If there is an Default ACL, send it to the Storage daemon */ - if (aclDef_text != NULL) { - sd = jcr->store_bsock; - pm_strcpy(&jcr->last_fname, ff_pkt->fname); - - - // Send ACL header - if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL)) { - berrno be; - Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), - bnet_strerror(sd)); - return 0; - } - - // Send the buffer to the storage deamon - msgsave = sd->msg; - sd->msg = aclDef_text; - sd->msglen = strlen(aclDef_text) + 1; - if (!bnet_send(sd)) { - berrno be; - sd->msg = msgsave; - sd->msglen = 0; - Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), - bnet_strerror(sd)); - } else { - jcr->JobBytes += sd->msglen; - sd->msg = msgsave; - if (!bnet_sig(sd, BNET_EOD)) { - berrno be; - Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), - bnet_strerror(sd)); - } else { - Dmsg1(200, "ACL of file: %s successfully backed up!\n", ff_pkt->fname); - } - } + /* Read access ACLs for files, dirs and links */ + if (!read_and_send_acl(jcr, BACL_TYPE_ACCESS, STREAM_UNIX_ATTRIBUTES_ACCESS_ACL)) { + return 0; + } + /* Directories can have default ACLs too */ + if (ff_pkt->type == FT_DIREND && (BACL_CAP & BACL_CAP_DEFAULTS_DIR)) { + if (!read_and_send_acl(jcr, BACL_TYPE_DEFAULT, STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL)) { + return 0; } } #endif @@ -529,8 +425,9 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) * Currently this is not a problem as the only other stream, resource forks, * are not handled as sparse files. */ -int send_data(int stream, FF_PKT *ff_pkt, BSOCK *sd, JCR *jcr, struct CHKSUM *chksum) +int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, struct CHKSUM *chksum) { + BSOCK *sd = jcr->store_bsock; uint64_t fileAddr = 0; /* file address */ char *rbuf, *wbuf; int rsize = jcr->buf_size; /* read buffer size */ @@ -642,7 +539,6 @@ int send_data(int stream, FF_PKT *ff_pkt, BSOCK *sd, JCR *jcr, struct CHKSUM *ch } sd->msg = wbuf; /* set correct write buffer */ if (!bnet_send(sd)) { - berrno be; Jmsg2(jcr, M_FATAL, 0, _("Network send error %d to SD. ERR=%s\n"), sd->msglen, bnet_strerror(sd)); sd->msg = msgsave; /* restore bnet buffer */ @@ -672,3 +568,55 @@ int send_data(int stream, FF_PKT *ff_pkt, BSOCK *sd, JCR *jcr, struct CHKSUM *ch return 1; } + +#ifdef HAVE_ACL +/* + * Read and send an ACL for the last encountered file. + */ +static int read_and_send_acl(JCR *jcr, int acltype, int stream) +{ + BSOCK *sd = jcr->store_bsock; + POOLMEM *msgsave; + int len; + + len = bacl_get(jcr, acltype); + if (len < 0) { + Jmsg1(jcr, M_WARNING, 0, "Error reading ACL of %s\n", jcr->last_fname); + return 1; + } + if (len == 0) { + return 1; /* no ACL */ + } + + /* Send header */ + if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, stream)) { + Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), + bnet_strerror(sd)); + return 0; + } + + /* Send the buffer to the storage deamon */ + Dmsg2(400, "Backing up ACL type 0x%2x <%s>\n", acltype, jcr->acl_text); + msgsave = sd->msg; + sd->msg = jcr->acl_text; + sd->msglen = len + 1; + if (!bnet_send(sd)) { + sd->msg = msgsave; + sd->msglen = 0; + Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), + bnet_strerror(sd)); + return 0; + } + + jcr->JobBytes += sd->msglen; + sd->msg = msgsave; + if (!bnet_sig(sd, BNET_EOD)) { + Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), + bnet_strerror(sd)); + return 0; + } + + Dmsg1(200, "ACL of file: %s successfully backed up!\n", jcr->last_fname); + return 1; +} +#endif diff --git a/bacula/src/filed/protos.h b/bacula/src/filed/protos.h index bac523bde4..952f56ff11 100644 --- a/bacula/src/filed/protos.h +++ b/bacula/src/filed/protos.h @@ -37,5 +37,5 @@ void start_dir_heartbeat(JCR *jcr); void stop_dir_heartbeat(JCR *jcr); /* From acl.c */ -POOLMEM *bacl_get(char *fname, int acltype); -int bacl_set(char *fname, int acltype, char *acltext); +int bacl_get(JCR *jcr, int acltype); +int bacl_set(JCR *jcr, int acltype); diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c index ada10e9cae..c3bcf1ca51 100644 --- a/bacula/src/filed/restore.c +++ b/bacula/src/filed/restore.c @@ -29,11 +29,6 @@ #include "bacula.h" #include "filed.h" -#ifdef HAVE_ACL -#include -#include -#endif - #ifdef HAVE_DARWIN_OS #include #endif @@ -102,9 +97,6 @@ void do_restore(JCR *jcr) int non_support_progname = 0; /* Finally, set up for special configurations */ -#ifdef HAVE_ACL - acl_t acl; -#endif #ifdef HAVE_DARWIN_OS intmax_t rsrc_len = 0; /* Original length of resource fork */ struct attrlist attrList; @@ -165,6 +157,7 @@ void do_restore(JCR *jcr) binit(&bfd); binit(&altbfd); attr = new_attr(); + jcr->acl_text = get_pool_memory(PM_MESSAGE); while (bget_msg(sd) >= 0 && !job_canceled(jcr)) { /* Remember previous stream type */ @@ -349,59 +342,30 @@ void do_restore(JCR *jcr) #else non_support_finfo++; #endif - break; -/*** FIXME ***/ -case STREAM_UNIX_ATTRIBUTES_ACCESS_ACL: + case STREAM_UNIX_ATTRIBUTES_ACCESS_ACL: #ifdef HAVE_ACL - /* Recover Acess ACL from stream and check it */ - acl = acl_from_text(sd->msg); - if (acl_valid(acl) != 0) { - Jmsg1(jcr, M_WARNING, 0, "Failure in the ACL of %s! FD is not able to restore it!\n", jcr->last_fname); - acl_free(acl); - } - - /* Try to restore ACL */ - if (attr->type == FT_DIREND) { - /* Directory */ - if (acl_set_file(jcr->last_fname, ACL_TYPE_ACCESS, acl) != 0) { - Jmsg1(jcr, M_WARNING, 0, "Error! Can't restore ACL of directory: %s! Maybe system does not support ACLs!\n", jcr->last_fname); - } - /* File or Link */ - } else if (acl_set_file(jcr->last_fname, ACL_TYPE_ACCESS, acl) != 0) { - Jmsg1(jcr, M_WARNING, 0, "Error! Can't restore ACL of file: %s! Maybe system does not support ACLs!\n", jcr->last_fname); + pm_strcpy(jcr->acl_text, sd->msg); + Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_ACCESS, jcr->acl_text); + if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) { + Jmsg1(jcr, M_WARNING, 0, "Can't restore ACL of %s\n", jcr->last_fname); } - acl_free(acl); - Dmsg1(200, "ACL of file: %s successfully restored!\n", jcr->last_fname); - break; -#else +#else non_support_acl++; - break; /* unconfigured, ignore */ #endif + break; + case STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL: #ifdef HAVE_ACL - /* Recover Default ACL from stream and check it */ - acl = acl_from_text(sd->msg); - if (acl_valid(acl) != 0) { - Jmsg1(jcr, M_WARNING, 0, "Failure in the Default ACL of %s! FD is not able to restore it!\n", jcr->last_fname); - acl_free(acl); + pm_strcpy(jcr->acl_text, sd->msg); + Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_DEFAULT, jcr->acl_text); + if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) { + Jmsg1(jcr, M_WARNING, 0, "Can't restore default ACL of %s\n", jcr->last_fname); } - - /* Try to restore ACL */ - if (attr->type == FT_DIREND) { - /* Directory */ - if (acl_set_file(jcr->last_fname, ACL_TYPE_DEFAULT, acl) != 0) { - Jmsg1(jcr, M_WARNING, 0, "Error! Can't restore Default ACL of directory: %s! Maybe system does not support ACLs!\n", jcr->last_fname); - } - } - acl_free(acl); - Dmsg1(200, "Default ACL of file: %s successfully restored!\n", jcr->last_fname); - break; -#else +#else non_support_acl++; - break; /* unconfigured, ignore */ #endif -/*** FIXME ***/ + break; case STREAM_MD5_SIGNATURE: case STREAM_SHA1_SIGNATURE: @@ -461,6 +425,7 @@ ok_out: bclose(&altbfd); bclose(&bfd); free_attr(attr); + free_pool_memory(jcr->acl_text); Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles, edit_uint64(jcr->JobBytes, ec1)); if (non_support_data > 1 || non_support_attr > 1) { @@ -535,9 +500,9 @@ int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, *addr = faddr; if (blseek(bfd, (off_t)*addr, SEEK_SET) < 0) { berrno be; - be.set_errno(bfd->berrno); Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"), - edit_uint64(*addr, ec1), jcr->last_fname, be.strerror()); + edit_uint64(*addr, ec1), jcr->last_fname, + be.strerror(bfd->berrno)); return -1; } } @@ -549,6 +514,11 @@ int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, if (flags & FO_GZIP) { #ifdef HAVE_LIBZ + /* + * NOTE! We only use uLong and Byte because they are + * needed by the zlib routines, they should not otherwise + * be used in Bacula. + */ compress_len = jcr->compress_buf_size; Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, wsize); if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len, @@ -568,11 +538,10 @@ int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1)); } - if ((uLong)bwrite(bfd, wbuf, wsize) != wsize) { - Dmsg0(0, "===Write error===\n"); + if (bwrite(bfd, wbuf, wsize) != (ssize_t)wsize) { berrno be; - be.set_errno(bfd->berrno); - Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), jcr->last_fname, be.strerror()); + Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), + jcr->last_fname, be.strerror(bfd->berrno)); return -1; } diff --git a/bacula/src/findlib/fstype.c b/bacula/src/findlib/fstype.c index a23d9aaa65..9bd5d574bd 100644 --- a/bacula/src/findlib/fstype.c +++ b/bacula/src/findlib/fstype.c @@ -45,17 +45,19 @@ "HAVE_NETBSD_OS\n" \ "HAVE_OPENBSD_OS\n" \ "HAVE_SUN_OS\n" -#define POOLMEM char -#define bstrdup strdup -#define Dmsg0(n,s) fprintf(stderr, s); -#define Dmsg1(n,s,a1) fprintf(stderr, s, a1); -#define Dmsg2(n,s,a1,a2) fprintf(stderr, s, a1, a2); +#define bool int +#define false 0 +#define true 1 +#define bstrncpy strncpy +#define Dmsg0(n,s) fprintf(stderr, s) +#define Dmsg1(n,s,a1) fprintf(stderr, s, a1) +#define Dmsg2(n,s,a1,a2) fprintf(stderr, s, a1, a2) #endif /* * These functions should be implemented for each OS * - * POOLMEM *fstype(const char *fname); + * bool fstype(const char *fname, char *fs, int fslen); */ #if defined(HAVE_DARWIN_OS) \ || defined(HAVE_FREEBSD_OS ) \ @@ -110,6 +112,17 @@ bool fstype(const char *fname, char *fs, int fslen) */ switch (st.f_type) { + /* Known good values */ + case 0xef53: bstrncpy(fs, "ext2", fslen); return true; /* EXT2_SUPER_MAGIC */ + /* case 0xef53: ext2 and ext3 are the same */ /* EXT3_SUPER_MAGIC */ + case 0x3153464a: bstrncpy(fs, "jfs", fslen); return true; /* JFS_SUPER_MAGIC */ + case 0x5346544e: bstrncpy(fs, "ntfs", fslen); return true; /* NTFS_SB_MAGIC */ + case 0x9fa0: bstrncpy(fs, "proc", fslen); return true; /* PROC_SUPER_MAGIC */ + case 0x52654973: bstrncpy(fs, "reiserfs", fslen); return true; /* REISERFS_SUPER_MAGIC */ + case 0x58465342: bstrncpy(fs, "xfs", fslen); return true; /* XFS_SB_MAGIC */ + case 0x9fa2: bstrncpy(fs, "usbdevfs", fslen); return true; /* USBDEVICE_SUPER_MAGIC */ + case 0x62656572: bstrncpy(fs, "sysfs", fslen); return true; /* SYSFS_MAGIC */ + #if 0 /* These need confirmation */ case 0xadf5: bstrncpy(fs, "adfs", fslen); return true; /* ADFS_SUPER_MAGIC */ case 0xadff: bstrncpy(fs, "affs", fslen); return true; /* AFFS_SUPER_MAGIC */ @@ -142,7 +155,6 @@ bool fstype(const char *fname, char *fs, int fslen) case 0x9660: bstrncpy(fs, "isofs", fslen); return true; /* ISOFS_SUPER_MAGIC */ case 0x07c0: bstrncpy(fs, "jffs", fslen); return true; /* JFFS_MAGIC_SB_BITMASK */ case 0x72b6: bstrncpy(fs, "jffs2", fslen); return true; /* JFFS2_SUPER_MAGIC */ - case 0x3153464a: bstrncpy(fs, "jfs", fslen); return true; /* JFS_SUPER_MAGIC */ case 0x2468: bstrncpy(fs, "minix", fslen); return true; /* MINIX2_SUPER_MAGIC */ case 0x2478: bstrncpy(fs, "minix", fslen); return true; /* MINIX2_SUPER_MAGIC2 */ case 0x137f: bstrncpy(fs, "minix", fslen); return true; /* MINIX_SUPER_MAGIC */ @@ -151,36 +163,26 @@ bool fstype(const char *fname, char *fs, int fslen) case 0x4d44: bstrncpy(fs, "msdos", fslen); return true; /* MSDOS_SUPER_MAGIC */ case 0x564c: bstrncpy(fs, "ncpfs", fslen); return true; /* NCP_SUPER_MAGIC */ case 0x6969: bstrncpy(fs, "nfs", fslen); return true; /* NFS_SUPER_MAGIC */ - case 0x5346544e: bstrncpy(fs, "ntfs", fslen); return true; /* NTFS_SB_MAGIC */ case 0x9fa1: bstrncpy(fs, "openpromfs", fslen); return true; /* OPENPROM_SUPER_MAGIC */ case 0x6f70726f: bstrncpy(fs, "oprofilefs", fslen); return true; /* OPROFILEFS_MAGIC */ case 0xa0b4d889: bstrncpy(fs, "pfmfs", fslen); return true; /* PFMFS_MAGIC */ case 0x50495045: bstrncpy(fs, "pipfs", fslen); return true; /* PIPEFS_MAGIC */ - case 0x9fa0: bstrncpy(fs, "proc", fslen); return true; /* PROC_SUPER_MAGIC */ case 0x002f: bstrncpy(fs, "qnx4", fslen); return true; /* QNX4_SUPER_MAGIC */ case 0x858458f6: bstrncpy(fs, "ramfs", fslen); return true; /* RAMFS_MAGIC */ - case 0x52654973: bstrncpy(fs, "reiserfs", fslen); return true; /* REISERFS_SUPER_MAGIC */ case 0x7275: bstrncpy(fs, "romfs", fslen); return true; /* ROMFS_MAGIC */ case 0x858458f6: bstrncpy(fs, "rootfs", fslen); return true; /* RAMFS_MAGIC */ case 0x67596969: bstrncpy(fs, "rpc_pipefs", fslen); return true; /* RPCAUTH_GSSMAGIC */ case 0x517B: bstrncpy(fs, "smbfs", fslen); return true; /* SMB_SUPER_MAGIC */ case 0x534F434B: bstrncpy(fs, "sockfs", fslen); return true; /* SOCKFS_MAGIC */ - case 0x62656572: bstrncpy(fs, "sysfs", fslen); return true; /* SYSFS_MAGIC */ case 0x012ff7b6: bstrncpy(fs, "sysv2", fslen); return true; /* SYSV2_SUPER_MAGIC */ case 0x012ff7b5: bstrncpy(fs, "sysv4", fslen); return true; /* SYSV4_SUPER_MAGIC */ case 0x858458f6: bstrncpy(fs, "tmpfs", fslen); return true; /* RAMFS_MAGIC */ case 0x01021994: bstrncpy(fs, "tmpfs", fslen); return true; /* TMPFS_MAGIC */ case 0x15013346: bstrncpy(fs, "udf", fslen); return true; /* UDF_SUPER_MAGIC */ case 0x00011954: bstrncpy(fs, "ufs", fslen); return true; /* UFS_MAGIC */ - case 0x9fa2: bstrncpy(fs, "usbdevfs", fslen); return true; /* USBDEVICE_SUPER_MAGIC */ case 0xa501FCF5: bstrncpy(fs, "vxfs", fslen); return true; /* VXFS_SUPER_MAGIC */ case 0x012ff7b4: bstrncpy(fs, "xenix", fslen); return true; /* XENIX_SUPER_MAGIC */ - case 0x58465342: bstrncpy(fs, "xfs", fslen); return true; /* XFS_SB_MAGIC */ case 0x012fd16d: bstrncpy(fs, "xiafs", fslen); return true; /* _XIAFS_SUPER_MAGIC */ - - case 0xef53: bstrncpy(fs, "ext2", fslen); return true; /* EXT2_SUPER_MAGIC */ - /* case 0xef53: ext2 and ext3 are the same */ /* EXT3_SUPER_MAGIC */ -#else /* Known good values */ #endif default: @@ -229,6 +231,7 @@ bool fstype(const char *fname, char *fs, int fslen) int main(int argc, char **argv) { char *p; + char fs[1000]; int status = 0; if (argc < 2) { @@ -239,10 +242,10 @@ int main(int argc, char **argv) return EXIT_FAILURE; } while (*++argv) { - if ((p = fstype(*argv)) == NULL) { + if (!fstype(*argv, fs, sizeof(fs))) { status = EXIT_FAILURE; } else { - printf("%s\t%s\n", p, *argv); + printf("%s\t%s\n", fs, *argv); } } return status; diff --git a/bacula/src/stored/bacula-sd.conf.in b/bacula/src/stored/bacula-sd.conf.in index b7c7b2ba02..434c431992 100644 --- a/bacula/src/stored/bacula-sd.conf.in +++ b/bacula/src/stored/bacula-sd.conf.in @@ -128,6 +128,21 @@ Device { # FreeSpaceCommand = "/etc/bacula/dvd-freespace %a %n" #} +# +# For OpenBSD OS >= 3.6 +# +#Device { +# Name = DDS-3 +# Media Type = DDS-3 +# Archive Device = /dev/nrst0 +# Use MTIOCGET= no +# BSF at EOM = yes +# TWO EOF = no +# AutomaticMount = yes; +# AlwaysOpen = yes; +# RemovableMedia = yes; +# RandomAccess = no; +#} # # A very old Exabyte with no end of media detection diff --git a/bacula/src/tools/fstype.c b/bacula/src/tools/fstype.c index 32abe6fa40..4003d62f8b 100644 --- a/bacula/src/tools/fstype.c +++ b/bacula/src/tools/fstype.c @@ -50,10 +50,10 @@ static void usage() int main (int argc, char *const *argv) { + char fs[1000]; int verbose = 0; int status = 0; int ch, i; - char fs[1000]; while ((ch = getopt(argc, argv, "v?")) != -1) { switch (ch) { diff --git a/bacula/src/version.h b/bacula/src/version.h index 42d2d4b31d..12dcce9cde 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #undef VERSION #define VERSION "1.37.2" -#define BDATE "11 January 2005" -#define LSMDATE "11Jan05" +#define BDATE "12 January 2005" +#define LSMDATE "12Jan05" /* Debug flags */ #undef DEBUG