*/
binit(&rctx.bfd);
binit(&rctx.forkbfd);
- attr = new_attr();
+ attr = new_attr(jcr);
jcr->acl_text = get_pool_memory(PM_MESSAGE);
#include "bacula.h"
#include "find.h"
+static uid_t my_uid = 1;
+static gid_t my_gid = 1;
+static bool uid_set = false;
+
+
#if defined(HAVE_WIN32)
/* Forward referenced subroutines */
static bool set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd);
bool ok = true;
boffset_t fsize;
+ if (uid_set) {
+ my_uid = getuid();
+ my_gid = getgid();
+ uid_set = true;
+ }
+
#if defined(HAVE_WIN32)
if (attr->stream == STREAM_UNIX_ATTRIBUTES_EX &&
set_win32_attributes(jcr, attr, ofd)) {
*/
if (attr->type == FT_LNK) {
/* Change owner of link, not of real file */
- if (lchown(attr->ofname, attr->statp.st_uid, attr->statp.st_gid) < 0) {
+ if (lchown(attr->ofname, attr->statp.st_uid, attr->statp.st_gid) < 0 && my_uid == 0) {
berrno be;
Jmsg2(jcr, M_ERROR, 0, _("Unable to set file owner %s: ERR=%s\n"),
attr->ofname, be.bstrerror());
ok = false;
}
} else {
- if (chown(attr->ofname, attr->statp.st_uid, attr->statp.st_gid) < 0) {
+ if (chown(attr->ofname, attr->statp.st_uid, attr->statp.st_gid) < 0 && my_uid == 0) {
berrno be;
Jmsg2(jcr, M_ERROR, 0, _("Unable to set file owner %s: ERR=%s\n"),
attr->ofname, be.bstrerror());
ok = false;
}
- if (chmod(attr->ofname, attr->statp.st_mode) < 0) {
+ if (chmod(attr->ofname, attr->statp.st_mode) < 0 && my_uid == 0) {
berrno be;
Jmsg2(jcr, M_ERROR, 0, _("Unable to set file modes %s: ERR=%s\n"),
attr->ofname, be.bstrerror());
/*
* Reset file times.
*/
- if (utime(attr->ofname, &ut) < 0) {
+ if (utime(attr->ofname, &ut) < 0 && my_uid == 0) {
berrno be;
Jmsg2(jcr, M_ERROR, 0, _("Unable to set file times %s: ERR=%s\n"),
attr->ofname, be.bstrerror());
* but if the immutable bit is set, it will make the utimes()
* fail.
*/
- if (chflags(attr->ofname, attr->statp.st_flags) < 0) {
+ if (chflags(attr->ofname, attr->statp.st_flags) < 0 && my_uid == 0) {
berrno be;
Jmsg2(jcr, M_ERROR, 0, _("Unable to set file flags %s: ERR=%s\n"),
attr->ofname, be.bstrerror());
* execute bit set (i.e. parent_mode), and preserve what already
* exists. Normally, this should do nothing.
*/
- if (!makepath(jcr, attr->ofname, parent_mode, parent_mode, uid, gid, 1)) {
+ if (!makepath(attr, attr->ofname, parent_mode, parent_mode, uid, gid, 1)) {
Dmsg1(10, "Could not make path. %s\n", attr->ofname);
attr->ofname[pnl] = savechr; /* restore full name */
return CF_ERROR;
case FT_DIRBEGIN:
case FT_DIREND:
Dmsg2(200, "Make dir mode=%o dir=%s\n", new_mode, attr->ofname);
- if (!makepath(jcr, attr->ofname, new_mode, parent_mode, uid, gid, 0)) {
+ if (!makepath(attr, attr->ofname, new_mode, parent_mode, uid, gid, 0)) {
return CF_ERROR;
}
/*
berrno be;
*created = false;
if (stat(path, &statp) != 0) {
- Jmsg(jcr, M_ERROR, 0, _("Cannot create directory %s: ERR=%s\n"),
+ Jmsg2(jcr, M_ERROR, 0, _("Cannot create directory %s: ERR=%s\n"),
path, be.bstrerror());
return false;
} else if (!S_ISDIR(statp.st_mode)) {
- Jmsg(jcr, M_ERROR, 0, _("%s exists but is not a directory.\n"), path);
+ Jmsg1(jcr, M_ERROR, 0, _("%s exists but is not a directory.\n"), path);
return false;
}
return true; /* directory exists */
return true;
}
-static void set_own_mod(JCR *jcr, char *path, uid_t owner, gid_t group, mode_t mode)
+static void set_own_mod(ATTR *attr, char *path, uid_t owner, gid_t group, mode_t mode)
{
- if (chown(path, owner, group) != 0
+ if (chown(path, owner, group) != 0 && attr->uid == 0
#ifdef AFS
&& errno != EPERM
#endif
) {
berrno be;
- Jmsg(jcr, M_WARNING, 0, _("Cannot change owner and/or group of %s: ERR=%s\n"),
+ Jmsg2(attr->jcr, M_WARNING, 0, _("Cannot change owner and/or group of %s: ERR=%s\n"),
path, be.bstrerror());
}
- if (chmod(path, mode) != 0) {
+ if (chmod(path, mode) != 0 && attr->uid == 0) {
berrno be;
- Jmsg(jcr, M_WARNING, 0, _("Cannot change permissions of %s: ERR=%s\n"),
+ Jmsg2(attr->jcr, M_WARNING, 0, _("Cannot change permissions of %s: ERR=%s\n"),
path, be.bstrerror());
}
}
*
* keep_dir_modes if set means don't change mode bits if dir exists
*/
-bool makepath(JCR *jcr, const char *apath, mode_t mode, mode_t parent_mode,
+bool makepath(ATTR *attr, const char *apath, mode_t mode, mode_t parent_mode,
uid_t owner, gid_t group, int keep_dir_modes)
{
struct stat statp;
int ndir = 0;
int i = 0;
int max_dirs = (int)sizeof(new_dir);
+ JCR *jcr = attr->jcr;
if (stat(path, &statp) == 0) { /* Does dir exist? */
if (!S_ISDIR(statp.st_mode)) {
- Jmsg(jcr, M_ERROR, 0, _("%s exists but is not a directory.\n"), path);
+ Jmsg1(jcr, M_ERROR, 0, _("%s exists but is not a directory.\n"), path);
return false;
}
/* Full path exists */
if (keep_dir_modes) {
return true;
}
- set_own_mod(jcr, path, owner, group, mode);
+ set_own_mod(attr, path, owner, group, mode);
return true;
}
omask = umask(0);
UINT drive_type = GetDriveType(drive);
if (drive_type == DRIVE_UNKNOWN || drive_type == DRIVE_NO_ROOT_DIR) {
- Jmsg(jcr, M_ERROR, 0, _("%c: is not a valid drive.\n"), path[0]);
+ Jmsg1(jcr, M_ERROR, 0, _("%c: is not a valid drive.\n"), path[0]);
goto bail_out;
}
new_dir[ndir++] = created;
}
if (ndir >= max_dirs) {
- Jmsg(jcr, M_WARNING, 0, _("Too many subdirectories. Some permissions not reset.\n"));
+ Jmsg0(jcr, M_WARNING, 0, _("Too many subdirectories. Some permissions not reset.\n"));
}
/* Now set the proper owner and modes */
save_p = *p;
*p = 0;
if (i < ndir && new_dir[i++] && !keep_dir_modes) {
- set_own_mod(jcr, path, owner, group, parent_mode);
+ set_own_mod(attr, path, owner, group, parent_mode);
}
*p = save_p;
while (IsPathSeparator(*p)) {
/* Set for final component */
if (i < ndir && new_dir[i++]) {
- set_own_mod(jcr, path, owner, group, mode);
+ set_own_mod(attr, path, owner, group, mode);
}
ok = true;
/* from makepath.c */
-int makepath(JCR *jcr, const char *path, mode_t mode,
+int makepath(ATTR *attr, const char *path, mode_t mode,
mode_t parent_mode, uid_t owner, gid_t group,
int keep_dir_modes);
#include "jcr.h"
#include "lib/breg.h"
-ATTR *new_attr()
+ATTR *new_attr(JCR *jcr)
{
ATTR *attr = (ATTR *)malloc(sizeof(ATTR));
memset(attr, 0, sizeof(ATTR));
attr->ofname = get_pool_memory(PM_FNAME);
attr->olname = get_pool_memory(PM_FNAME);
attr->attrEx = get_pool_memory(PM_FNAME);
+ attr->jcr = jcr;
+ attr->uid = getuid();
return attr;
}
* Version $Id$
*/
+#ifndef __ATTR_H_
+#define __ATTR_H_ 1
+
struct ATTR {
int32_t stream; /* attribute stream id */
int32_t type; /* file type FT */
int32_t file_index; /* file index */
int32_t LinkFI; /* file index to data if hard link */
+ uid_t uid; /* userid */
struct stat statp; /* decoded stat packet */
POOLMEM *attrEx; /* extended attributes if any */
POOLMEM *ofname; /* output filename */
char *attr; /* attributes position */
char *fname; /* filename */
char *lname; /* link name if any */
+ JCR *jcr; /* jcr pointer */
};
+
+#endif /* __ATTR_H_ */
bmicrosleep(5, 0);
return false;
}
- Dmsg1(100, "cram-get: %s", bs->msg);
+ Dmsg1(100, "cram-get received: %s", bs->msg);
if (sscanf(bs->msg, "auth cram-md5c %s ssl=%d", chal, tls_remote_need) == 2) {
*compatible = true;
} else if (sscanf(bs->msg, "auth cram-md5 %s ssl=%d", chal, tls_remote_need) != 2) {
if (strcmp(bs->msg, "1000 OK auth\n") == 0) {
return true;
}
- Dmsg1(50, "Bad auth response: %s\n", bs->msg);
+ Dmsg1(50, "Received bad response: %s\n", bs->msg);
bmicrosleep(5, 0);
return false;
}
sitem.gid = gid;
char buf[50];
- item = (guitem *)uid_list->binary_search(&sitem, gid_compare);
+ item = (guitem *)gid_list->binary_search(&sitem, gid_compare);
if (!item) {
item = (guitem *)malloc(sizeof(guitem));
item->gid = gid;
class JCR;
/* attr.c */
-ATTR *new_attr();
+ATTR *new_attr(JCR *jcr);
void free_attr(ATTR *attr);
int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr);
void build_attr_output_fnames(JCR *jcr, ATTR *attr);
free(jcr->where);
jcr->where = bstrdup(where);
- attr = new_attr();
+ attr = new_attr(jcr);
compress_buf = get_memory(compress_buf_size);
}
dcr = jcr->dcr;
rec = new_record();
- attr = new_attr();
+ attr = new_attr(jcr);
/*
* Assume that we have already read the volume label.
* If on second or subsequent volume, adjust buffer pointer
static void do_scan()
{
- attr = new_attr();
+ attr = new_attr(bjcr);
memset(&ar, 0, sizeof(ar));
memset(&pr, 0, sizeof(pr));
Technical notes on version 2.3
General:
+08Sep07
+kes Suppress chown and chmod error messages if the FD is not running
+ as root.
07Sep07
kes Apply Martin Simmons patch that should turn off the new API usage
when batch insert is turned off allowing building on older
PostgreSQLs.
kes Add ./configure search in qwt-qt4 for qwt package
05Sep07
+kes Bacula is now free of 3rd party GPL copyrighted code!
kes Remove idcache.c
kes Add guid_to_name.c/h which replace idcache.
kes Remove enh_fnmatch.c. Make code that references it use fnmatch.c