redmine

Separated privileged thread

... ... @@ -7,41 +7,42 @@ bin_PROGRAMS = clsync
clsync_SOURCES = calc.c cluster.c error.c fileutils.c glibex.c \
indexes.c main.c malloc.c stringex.c sync.c calc.h cluster.h \
fileutils.h glibex.h main.h port-hacks.h stringex.h sync.h \
common.h control.h
common.h control.h privileged.h
clsync_CFLAGS = $(AM_CFLAGS)
if HAVE_KQUEUE
clsync_CFLAGS += -DKQUEUE_SUPPORT
clsync_CFLAGS += -DKQUEUE_SUPPORT
clsync_SOURCES += mon_kqueue.c mon_kqueue.h
endif
if HAVE_INOTIFY
clsync_CFLAGS += -DINOTIFY_SUPPORT
clsync_CFLAGS += -DINOTIFY_SUPPORT
clsync_SOURCES += mon_inotify.c mon_inotify.h
if INOTIFY_OLD
clsync_CFLAGS += -DINOTIFY_OLD
clsync_CFLAGS += -DINOTIFY_OLD
endif
endif
if HAVE_FANOTIFY
clsync_CFLAGS += -DFANOTIFY_SUPPORT
clsync_CFLAGS += -DFANOTIFY_SUPPORT
clsync_SOURCES += mon_fanotify.c mon_fanotify.h
endif
if HAVE_BSM
clsync_CFLAGS += -DBSM_SUPPORT
clsync_CFLAGS += -DBSM_SUPPORT
clsync_SOURCES += mon_bsm.c mon_bsm.h
endif
if HAVE_DTRACEPIPE
clsync_CFLAGS += -DDTRACEPIPE_SUPPORT
clsync_CFLAGS += -DDTRACEPIPE_SUPPORT
clsync_SOURCES += mon_dtracepipe.c mon_dtracepipe.h
endif
if HAVE_BACKTRACE
clsync_CFLAGS += -DBACKTRACE_SUPPORT
clsync_CFLAGS += -DBACKTRACE_SUPPORT
endif
if HAVE_CAPABILITIES
clsync_CFLAGS += -DCAPABILITIES_SUPPORT
clsync_CFLAGS += -DCAPABILITIES_SUPPORT
clsync_SOURCES += privileged.c
endif
if HAVE_GETMNTENT
clsync_CFLAGS += -DGETMNTENT_SUPPORT
clsync_CFLAGS += -DGETMNTENT_SUPPORT
endif
if SOCKET
... ...
... ... @@ -145,3 +145,11 @@ filesz:1M\n\
"--exclude=*", \
NULL }
#define DEFAULT_PRESERVE_CAPABILITIES ( CAP_TO_MASK(CAP_DAC_READ_SEARCH) | CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SETGID) )
#define DEFAULT_UID 65535
#define DEFAULT_GID 65535
#define DEFAULT_SYNCHANDLER_UID 0
#define DEFAULT_SYNCHANDLER_GID 0
... ...
... ... @@ -22,6 +22,9 @@
#define __CLSYNC_CTX_H
#include <regex.h>
#ifdef CAPABILITIES_SUPPORT
# include <sys/capability.h> // __u32
#endif
#define OPTION_FLAGS (1<<10)
#define OPTION_LONGOPTONLY (1<<9)
... ... @@ -40,7 +43,7 @@ enum flags_enum {
BACKGROUND = 'b',
UID = 'u',
GID = 'g',
CAP_PRESERVE_FILEACCESS = 'C',
CAP_PRESERVE = 'C',
THREADING = 'p',
RETRIES = 'r',
OUTPUT_METHOD = 'Y',
... ... @@ -108,6 +111,9 @@ enum flags_enum {
#ifdef GETMNTENT_SUPPORT
MOUNTPOINTS = 25|OPTION_LONGOPTONLY,
#endif
NOTHREADSPLITTING = 26|OPTION_LONGOPTONLY,
SYNCHANDLERUID = 27|OPTION_LONGOPTONLY,
SYNCHANDLERGID = 28|OPTION_LONGOPTONLY,
};
typedef enum flags_enum flags_t;
... ... @@ -230,6 +236,11 @@ struct ctx {
size_t pid_str_len;
uid_t uid;
gid_t gid;
#ifdef CAPABILITIES_SUPPORT
uid_t synchandler_uid;
gid_t synchandler_gid;
__u32 caps;
#endif
pid_t child_pid[MAXCHILDREN]; // Used only for non-pthread mode
int children; // Used only for non-pthread mode
uint32_t iteration_num;
... ...
This diff is collapsed. Click to expand it.
... ... @@ -186,7 +186,7 @@ Use configuration block with name
(see
.BR "CONFIGURATION FILE" ).
Default value is "default".
The default value is "default".
.PP
.RE
... ... @@ -204,7 +204,7 @@ Options from
will be inherited to
.IR config\-block\-name .
Default value is "default".
The default value is "default".
.PP
.RE
... ... @@ -229,7 +229,7 @@ And clsync will use options from config block "debug" on signal 29 and
To reset all custom signals use the 0-th signal (e.g. "\-\-custom\-signals=0").
Default value is "".
The default value is "".
.PP
.RE
... ... @@ -308,7 +308,9 @@ Drop user privileges to uid
with
.BR setuid (2)
Is not set by default.
If there's a
.BR capabilities (7)
support then the default value is "65535", otherwise the option is not set by default;
.PP
.RE
... ... @@ -320,34 +322,135 @@ Drop group privileges to gid
with
.BR setgid (2)
Is not set by default.
If there's a
.BR capabilities (7)
support then the default value is "65535", otherwise the option is not set by default;
.PP
.RE
.B \-C, \-\-preserve\-file\-access
.B \-\-sync\-handler\-uid
.I sync\-handler\-uid
.RS
.B [Linux only]
.B [Linux only, requires capabilities]
An user ID to be used for
.IR sync\-handler .
See
.BR \-\-preserve\-capabilities .
This option is ignored if the
.B clsync
instance have no CAP_SETUID capability or if option
.B --no-thread-splitting
is enabled.
The default value is "0".
.PP
.RE
.B \-\-sync\-handler\-gid
.I sync\-handler\-gid
.RS
.B [Linux only, requires capabilities]
A group ID to be used for
.IR sync\-handler .
See
.BR \-\-preserve\-capabilities .
This option is ignored if the
.B clsync
instance have no CAP_SETGID capability or if option
.B --no-thread-splitting
is enabled.
The default value is "0".
.PP
.RE
.B \-C, \-\-preserve\-capabilities
.I capabilities\-list
.RS
.B [Linux only, requires capabilities]
Use
.BR capset (2)
and
.BR prctl (2)
to preserve "CAP_DAC_READ_SEARCH" [see
to preserve "CAP_DAC_READ_SEARCH", "CAP_SETUID" or/and "CAP_SETGID" [see
.BR capabilities (7)]
Linux capability. This allows to preserve full FS read access after dropping
privilegies using
.BR setuid (2)
Linux capability for thread using
.BR fts "(3), " inotify "(7) and " execve "(2)."
This allows to preserve enough FS privileges to watch a file tree and execute
the
.I sync\-handler
with required uid and gid [see
.B \-\-sync\-handler\-uid
and
.BR setgid (2)
.BR \-\-sync\-handler\-gid ]
after dropping privileges via
.BR setuid "(2) and " setgid "(2)"
[see
.B \-\-uid
and
.BR \-\-gid ]
Is not set by default.
Possible values:
.RS
.B CAP_DAC_READ_SEARCH
.RS
To bypass FS read checks (for
.BR fts " and " inotify ).
.RE
.B CAP_SETUID
.RS
To be able to use
.BR setuid (2)
before
.BR execve (2)
on the
.BR sync\-handler .
.RE
.B CAP_SETGID
.RS
To be able to use
.BR setgid (2)
before
.BR execve (2)
on the
.BR sync\-handler .
.RE
.br
.br
Any combinations of this values are also supported. The list may be presented
as a comma separated values, like:
.RS
CAP_DAC_READ_SEARCH,CAP_SETUID,CAP_SETGID
.RE
.RE
The default value is "CAP_DAC_READ_SEARCH,CAP_SETUID,CAP_SETGID" if the
.B clsync
runner have such privileges.
.PP
.RE
.B \-\-no\-thread\-splitting
.RS
.B [Linux only, requires capabilities]
Don't split the main thread to privileged and non-privileged. This may be used
due to performance reasons. Performance vs security trade off.
The thread splitting is used only on Linux systems.
Is not set by default.
.RE
.B \-\-chroot
.I chroot\-directory
.RS
... ... @@ -402,7 +505,7 @@ Delay between tries is equal to
.I \-\-delay\-sync
value.
Default value is "1".
The default value is "1".
.RE
.B \-\-ignore\-failures
... ... @@ -475,7 +578,7 @@ you may catch a bug due to nonatomicity of rsync's file replace operation.
(see
.BR DIAGNOSTICS )
Default value is "off".
The default value is "off".
.RE
.B \-Y, \-\-output
... ... @@ -492,7 +595,7 @@ Possible values:
.I syslog
.RE
Default value is "stderr".
The default value is "stderr".
.RE
.B \-\-one\-file\-system
... ... @@ -565,7 +668,7 @@ This option can be used only in conjunction with
Use IP-addresses from 224.0.0.0/4 for this option.
Default value is "227.108.115.121". [(128+"c")."l"."s"."y"]
The default value is "227.108.115.121". [(128+"c")."l"."s"."y"]
.RE
.PP
... ... @@ -582,7 +685,7 @@ This option can be used only in conjunction with
.I multicast\-port
should be greater than 0 and less than 65535.
Default value is "40079". [("n" << 8) + "c"]
The default value is "40079". [("n" << 8) + "c"]
.RE
.PP
... ... @@ -594,7 +697,7 @@ Default value is "40079". [("n" << 8) + "c"]
Sets timeout (in milliseconds) of waiting answer from another nodes of the
cluster. If there's no answer from some node, it will be excluded.
Default value is "1000". [1 second]
The default value is "1000". [1 second]
.RE
.PP
... ... @@ -607,7 +710,7 @@ Sets the name of current node in the cluster. It will be used in action
scripts of another nodes (see
.BR "SYNC HANDLER MODES" ).
Default value is $(uname \-n).
The default value is $(uname \-n).
.RE
.PP
... ... @@ -617,7 +720,7 @@ Default value is $(uname \-n).
Sets minimal directory level for ctime hashing (see
.BR CLUSTERING ).
Default value is "1".
The default value is "1".
.RE
.PP
... ... @@ -629,7 +732,7 @@ Default value is "1".
Sets maximal directory level for ctime hashing (see
.BR CLUSTERING ).
Default value is "16".
The default value is "16".
.RE
.PP
... ... @@ -641,7 +744,7 @@ Default value is "16".
Sets maximal directory level for ctime scanning (see
.BR CLUSTERING ).
Default value is "32".
The default value is "32".
.RE
.PP
... ... @@ -674,7 +777,7 @@ set to n means that only initial sync and (n-1) sync-ups after that will be done
Hint: This option may be useful in conjunction with \-\-exit\-on\-no\-events
to prevent infinite sync-up processes.
Default value is "0".
The default value is "0".
.RE
.PP
... ... @@ -689,7 +792,7 @@ seconds.
Set "0" to disable the timeout.
Default value is "86400" ["24 hours"].
The default value is "86400" ["24 hours"].
.RE
.PP
... ... @@ -698,7 +801,7 @@ Default value is "86400" ["24 hours"].
.RS
Sets the minimal delay (in seconds) between syncs.
Default value is "30".
The default value is "30".
.RE
.PP
... ... @@ -708,7 +811,7 @@ Default value is "30".
Sets the delay (in seconds) to collect events about ordinary files and
directories.
Default value is "30".
The default value is "30".
.RE
.PP
... ... @@ -718,7 +821,7 @@ Default value is "30".
Sets the delay (in seconds) to collect events about "big files" (see
.IR \-\-threshold\-bigfile ).
Default value is "1800".
The default value is "1800".
.RE
.PP
... ... @@ -730,7 +833,7 @@ Sets file size threshold (in bytes) that separates ordinary files from
separate collecting delay. This is supposed to be used as a means of unloading
IO resources.
Default value is "134217728" ["128 MiB"].
The default value is "134217728" ["128 MiB"].
.RE
.PP
... ... @@ -792,7 +895,7 @@ splits that list with approximately
lines per list if it's too big, and executes by one rsync instance per list
part. Use value "0" to disable the limit.
Default value is "20000".
The default value is "20000".
.RE
.PP
... ... @@ -1068,7 +1171,7 @@ will be passed to
.I sync\-handler
every execution.
Default value is "nolabel".
The default value is "nolabel".
.RE
.PP
... ...
... ... @@ -22,6 +22,7 @@
#include "error.h"
#include "sync.h"
#include "indexes.h"
#include "privileged.h"
#include "mon_inotify.h"
enum event_bits {
... ... @@ -67,7 +68,7 @@ static inline uint32_t recognize_event(uint32_t event) {
int inotify_add_watch_dir(ctx_t *ctx_p, indexes_t *indexes_p, const char *const accpath) {
int inotify_d = (int)(long)ctx_p->fsmondata;
return inotify_add_watch(inotify_d, accpath, INOTIFY_MARKMASK);
return privileged_inotify_add_watch(inotify_d, accpath, INOTIFY_MARKMASK);
}
int inotify_wait(ctx_t *ctx_p, struct indexes *indexes_p, struct timeval *tv_p) {
... ...
This diff is collapsed. Click to expand it.
/*
clsync - file tree sync utility based on inotify/kqueue
Copyright (C) 2013-2014 Dmitry Yu Okunev <dyokunev@ut.mephi.ru> 0x8E30679C
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef CAPABILITIES_SUPPORT
extern int privileged_init(struct ctx *ctx_p);
extern int privileged_deinit(struct ctx *ctx_p);
extern FTS *(*privileged_fts_open) (
char * const *path_argv,
int options,
int (*compar)(const FTSENT **, const FTSENT **)
);
extern FTSENT *(*privileged_fts_read) (FTS *ftsp);
extern int (*privileged_fts_close) (FTS *ftsp);
extern int (*privileged_inotify_init) ();
extern int (*privileged_inotify_init1) (int flags);
extern int (*privileged_inotify_add_watch) (
int fd,
const char *pathname,
uint32_t mask
);
extern int (*privileged_inotify_rm_watch) (
int fd,
int wd
);
#else
#define privileged_fts_open fts_open
#define privileged_fts_read fts_read
#define privileged_fts_close fts_close
#define privileged_inotify_init inotify_init
#define privileged_inotify_init1 inotify_init1
#define privileged_inotify_add_watch inotify_add_watch
#define privileged_inotify_rm_watch inotify_rm_watch
#endif
extern int (*privileged_fork_execvp)(const char *file, char *const argv[]);
... ...
This diff is collapsed. Click to expand it.