diff options
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/config.c | 82 | ||||
-rw-r--r-- | src/directive.c | 2 | ||||
-rw-r--r-- | src/diskio.c | 68 | ||||
-rw-r--r-- | src/lock.c | 2 | ||||
-rw-r--r-- | src/mail.c | 2 | ||||
-rw-r--r-- | src/triplet.c | 6 | ||||
-rw-r--r-- | src/userprivs.c | 118 | ||||
-rw-r--r-- | src/wydawca.c | 90 | ||||
-rw-r--r-- | src/wydawca.h | 14 |
10 files changed, 260 insertions, 125 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index c91669e..993ce0d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -33,12 +33,13 @@ wydawca_SOURCES=\ pidfile.c\ process.c\ sql.c\ sql.h\ tcpwrap.c\ triplet.c\ + userprivs.c\ verify.c\ wydawca.c\ wydawca.h\ mail.h\ mail.c\ vtab.c\ diff --git a/src/config.c b/src/config.c index b1f339f..b6e2533 100644 --- a/src/config.c +++ b/src/config.c @@ -975,12 +975,13 @@ cb_access_method_params (enum gconf_callback_command cmd, if (assert_string_arg (locus, cmd, vp)) break; meth->parmv[i] = xstrdup (vp->v.string); } + gl_list_iterator_free (&itr); meth->parmv[i] = NULL; } return 0; } static struct gconf_keyword access_method_kw[] = { @@ -1221,12 +1222,88 @@ cb_spool (enum gconf_callback_command cmd, gconf_error (locus, 0, _("invalid use of block statement")); } return 0; } +static int +cb_user (enum gconf_callback_command cmd, + gconf_locus_t *locus, + void *varptr, + gconf_value_t *value, + void *cb_data) +{ + int rc; + struct passwd *pw; + + if (assert_string_arg (locus, cmd, value)) + return 1; + + pw = getpwnam (value->v.string); + if (!pw) + { + gconf_error (locus, 0, _("no such user: %s"), value->v.string); + return 1; + } + + wydawca_uid = pw->pw_uid; + wydawca_gid = pw->pw_gid; + return 0; +} + +static int +cb_supp_groups (enum gconf_callback_command cmd, + gconf_locus_t *locus, + void *varptr, + gconf_value_t *value, + void *cb_data) +{ + if (cmd != gconf_callback_set_value) + { + gconf_error (locus, 0, _("Unexpected block statement")); + return 1; + } + if (!value || value->type != GCONF_TYPE_LIST) + { + gconf_error (locus, 0, _("expected list value")); + return 1; + } + + wydawca_supp_groupc = gl_list_size (value->v.list); + if (wydawca_supp_groupc == 0) + wydawca_supp_groups = NULL; + else + { + int i; + gl_list_iterator_t itr; + const void *p; + + wydawca_supp_groups = xcalloc (wydawca_supp_groupc, + sizeof (wydawca_supp_groups[0])); + itr = gl_list_iterator (value->v.list); + for (i = 0; gl_list_iterator_next (&itr, &p, NULL); i++) + { + const gconf_value_t *vp = p; + struct group *grp; + + if (assert_string_arg (locus, cmd, vp)) + break; + grp = getgrnam (vp->v.string); + if (!grp) + { + gconf_error (locus, 0, _("no such group: %s"), value->v.string); + break; + } + wydawca_supp_groups[i] = grp->gr_gid; + } + gl_list_iterator_free (&itr); + } + return 0; +} + + static struct gconf_keyword wydawca_kw[] = { { "daemon", NULL, N_("Enable daemon mode"), gconf_type_bool, &daemon_mode }, { "foreground", NULL, N_("Start in foreground even in daemon mode"), gconf_type_bool, &foreground }, @@ -1234,12 +1311,17 @@ static struct gconf_keyword wydawca_kw[] = { gconf_type_bool, &single_process }, { "wakeup-interval", N_("time"), N_("Set wake-up interval"), gconf_type_string, &wakeup_interval, 0, cb_interval }, { "pidfile", N_("file"), N_("Set pid file name"), gconf_type_string, &pidfile }, + { "user", N_("name"), N_("Run with UID and GID of this user"), + gconf_type_string, NULL, 0, cb_user }, + { "group", NULL, N_("Retain these supplementary groups"), + gconf_type_string|GCONF_LIST, NULL, 0, cb_supp_groups }, + { "locking", NULL, N_("Enable or disable locking"), gconf_type_bool, &enable_locking }, { "lockdir", N_("dir"), N_("Set directory for lock files"), gconf_type_string, &lockdir }, { "lock-expire-time", N_("interval"), N_("Define lock expiration interval"), gconf_type_string, &lock_expire_time, 0, cb_interval }, diff --git a/src/directive.c b/src/directive.c index 2915fee..416095f 100644 --- a/src/directive.c +++ b/src/directive.c @@ -334,15 +334,13 @@ process_directives (struct file_triplet *trp, const struct spool *spool) trp->file[file_directive].name, val); return 1; } break; case filename_dir: - wydawca_set_root_privs (); rc = verify_detached_signature (trp, spool); - wydawca_set_triplet_privs (trp); if (rc == 0) { if (move_file (trp, spool, file_dist, relative_dir) || move_file (trp, spool, file_signature, relative_dir)) return 1; } diff --git a/src/diskio.c b/src/diskio.c index fbd1050..35ba71e 100644 --- a/src/diskio.c +++ b/src/diskio.c @@ -55,15 +55,15 @@ concat_dir (const char *base, const char *name, size_t *pbaselen) if (pbaselen) *pbaselen = len; return dir; } /* Create the directory DIR, eventually creating all intermediate directories - starting from DIR + BASELEN, with owner UID and GID. */ + starting from DIR + BASELEN. */ int -create_hierarchy (char *dir, size_t baselen, uid_t uid, gid_t gid) +create_hierarchy (char *dir, size_t baselen) { int rc; struct stat st; char *p; if (stat (dir, &st) == 0) @@ -89,60 +89,51 @@ create_hierarchy (char *dir, size_t baselen, uid_t uid, gid_t gid) logmsg (LOG_ERR, _("base directory %s does not exist"), dir); return 1; } *p = 0; } - rc = create_hierarchy (dir, baselen, uid, gid); + rc = create_hierarchy (dir, baselen); if (rc == 0) { if (p) *p = '/'; if (mkdir (dir, MKDIR_PERMISSIONS)) { logmsg (LOG_ERR, _("cannot create directory %s: %s"), dir, strerror (errno)); rc = 1; } - if (chown (dir, uid, gid)) - { - logmsg (LOG_NOTICE, _("cannot change ownership of %s: %s"), - dir, strerror (errno)); - } } return rc; } /* Create a directory BASE/NAME (with eventual intermediate directories in NAME). Use UID and GID as owner ids. Do nothing if dry_run_mode is set. */ char * -create_directory (const char *base, const char *name, uid_t uid, gid_t gid) +create_directory (const char *base, const char *name) { size_t baselen; char *dir = concat_dir (base, name, &baselen); if (!dry_run_mode) { - int rc; - wydawca_set_root_privs (); - rc = create_hierarchy (dir, baselen, uid, gid); - wydawca_set_privs (uid, gid); - if (rc) + if (create_hierarchy (dir, baselen)) { free (dir); dir = NULL; } } return dir; } -/* Copy FILE to DST_FILE, creating the latter with owner UID and GID. */ +/* Copy FILE to DST_FILE. */ int -copy_file (const char *file, const char *dst_file, uid_t uid, gid_t gid) +copy_file (const char *file, const char *dst_file) { int in_fd, out_fd; struct stat st; int rc; char *buf; size_t bufsize; @@ -220,24 +211,23 @@ copy_file (const char *file, const char *dst_file, uid_t uid, gid_t gid) if (rc) unlink (dst_file); return rc; } /* Move FILE to DST_FILE. If they reside on different devices, use copy_file - + unlink. - UID and GID give DST_FILE ownership. */ + + unlink. */ int -do_move_file (const char *file, const char *dst_file, uid_t uid, gid_t gid) +do_move_file (const char *file, const char *dst_file) { int rc = 0; if (rename (file, dst_file)) { if (errno == EXDEV) { - if (copy_file (file, dst_file, uid, gid)) + if (copy_file (file, dst_file)) { logmsg (LOG_CRIT, _("cannot copy %s to %s: %s"), file, dst_file, strerror (errno)); rc = 1; } else if (unlink (file)) @@ -296,29 +286,28 @@ tar_append_file (const char *archive, const char *file) /* Backup a file to a directory. Arguments: DST_FILE - File nam to back up. DST_DIR - Directory part of DST_FILE. FILE - File part of DST_FILE; can contain subdirs. ARCHIVE - Archive descriptor. - UID, GID - Ownership RELDIR - Directory part of FILE Do nothing if dry_run_mode is set. */ int backup_file (const char *dst_file, const char *dst_dir, const char *file, - const struct archive_descr *archive, uid_t uid, gid_t gid, + const struct archive_descr *archive, const char *reldir) { int rc = 0; char *adir; char *file_name; if (archive->name[0] == '/') - adir = create_directory (archive->name, reldir, uid, gid); + adir = create_directory (archive->name, reldir); else - adir = create_directory (dst_dir, archive->name, uid, gid); + adir = create_directory (dst_dir, archive->name); if (!adir) return 1; file_name = concat_dir (adir, file, NULL); if (access (file_name, F_OK) == 0) { @@ -344,13 +333,13 @@ backup_file (const char *dst_file, const char *dst_dir, const char *file, if (debug_level) logmsg (LOG_DEBUG, _("backing up previous archive file `%s' to `%s'"), file_name, archive_file_name); if (!dry_run_mode) { - rc = do_move_file (file_name, archive_file_name, uid, gid); + rc = do_move_file (file_name, archive_file_name); if (rc) { logmsg (LOG_ERR, _("backing `%s' up as `%s' failed: %s"), file_name, archive_file_name, strerror (errno)); free (archive_file_name); free (file_name); @@ -363,13 +352,13 @@ backup_file (const char *dst_file, const char *dst_dir, const char *file, } if (debug_level) logmsg (LOG_DEBUG, _("archiving `%s' to `%s'"), dst_file, file_name); if (!dry_run_mode) { - rc = do_move_file (dst_file, file_name, uid, gid); + rc = do_move_file (dst_file, file_name); if (rc) logmsg (LOG_ERR, _("archiving `%s' as `%s' failed: %s"), dst_file, file_name, strerror (errno)); } free (file_name); free (adir); @@ -377,22 +366,22 @@ backup_file (const char *dst_file, const char *dst_dir, const char *file, } /* Select the appropriate backup type and backup a file. See backup_file for the argument description. */ int do_archive_file (const char *dst_file, const char *dst_dir, const char *file, - const struct archive_descr *archive, uid_t uid, gid_t gid, + const struct archive_descr *archive, const char *reldir) { switch (archive->type) { case archive_none: break; case archive_directory: - return backup_file (dst_file, dst_dir, file, archive, uid, gid, reldir); + return backup_file (dst_file, dst_dir, file, archive, reldir); case archive_tar: if (tar_append_file (archive->name, dst_file)) return 1; } if (!dry_run_mode && unlink (dst_file)) @@ -412,31 +401,28 @@ do_archive_file (const char *dst_file, const char *dst_dir, const char *file, int dir_move_file (struct file_triplet *trp, const struct spool *spool, enum file_type file_id, const char *reldir) { char *dst_file; int rc = 0; - char *dst_dir = create_directory (spool->dest_dir, reldir, - TRIPLET_UID (trp), TRIPLET_GID (trp)); + char *dst_dir = create_directory (spool->dest_dir, reldir); if (!dst_dir) return 1; dst_file = concat_dir (dst_dir, trp->file[file_id].name, NULL); if (debug_level) logmsg (LOG_DEBUG, _("installing %s to %s"), trp->file[file_id].name, dst_dir); if (access (dst_file, F_OK) == 0) rc = do_archive_file (dst_file, dst_dir, trp->file[file_id].name, - &spool->archive, - TRIPLET_UID (trp), TRIPLET_GID (trp), reldir); + &spool->archive, reldir); if (!dry_run_mode && rc == 0) - rc = do_move_file (trp->file[file_id].name, dst_file, - TRIPLET_UID (trp), TRIPLET_GID (trp)); + rc = do_move_file (trp->file[file_id].name, dst_file); free (dst_file); free (dst_dir); if (rc == 0) UPDATE_STATS (STAT_UPLOADS); return rc; @@ -450,14 +436,13 @@ int archive_single_file (struct file_triplet *trp, const struct spool *spool, const char *file_name, const char *reldir, int noentok) { char *dst_file; int rc = 0; - char *dst_dir = create_directory (spool->dest_dir, reldir, - TRIPLET_UID (trp), TRIPLET_GID (trp)); + char *dst_dir = create_directory (spool->dest_dir, reldir); if (!dst_dir) return 1; dst_file = safe_file_name (concat_dir (dst_dir, file_name, NULL)); if (!sub_dir_p (dst_file, spool->dest_dir)) @@ -471,13 +456,13 @@ archive_single_file (struct file_triplet *trp, const struct spool *spool, if (access (dst_file, F_OK) == 0) { if (debug_level) logmsg (LOG_DEBUG, _("archiving file `%s'"), dst_file); rc = do_archive_file (dst_file, dst_dir, file_name, &spool->archive, - TRIPLET_UID (trp), TRIPLET_GID (trp), reldir); + reldir); if (rc == 0) UPDATE_STATS (STAT_ARCHIVES); } else if (errno == ENOENT) { if (!noentok) @@ -540,14 +525,13 @@ int dir_symlink_file (struct file_triplet *trp, const struct spool *spool, const char *reldir, const char *wanted_src, const char *wanted_dst) { int rc = 0; struct saved_cwd cwd; - char *dst_dir = create_directory (spool->dest_dir, reldir, - TRIPLET_UID (trp), TRIPLET_GID (trp)); + char *dst_dir = create_directory (spool->dest_dir, reldir); char *src, *dst; if (!dst_dir) return 1; if (save_cwd (&cwd)) @@ -585,14 +569,13 @@ dir_symlink_file (struct file_triplet *trp, const struct spool *spool, char *p = strrchr (dst, '/'); if (p > dst) { char *dir; *p = 0; - dir = create_directory (spool->dest_dir, dst, - TRIPLET_UID (trp), TRIPLET_GID (trp)); + dir = create_directory (spool->dest_dir, dst); if (!dir) rc = 1; else free (dir); *p = '/'; } @@ -700,14 +683,13 @@ int dir_rmsymlink_file (struct file_triplet *trp, const struct spool *spool, const char *reldir, const char *file_name) { char *dst_file; int rc = 0; char *signame; - char *dst_dir = create_directory (spool->dest_dir, reldir, - TRIPLET_UID (trp), TRIPLET_GID (trp)); + char *dst_dir = create_directory (spool->dest_dir, reldir); if (!dst_dir) return 1; dst_file = safe_file_name (concat_dir (dst_dir, file_name, NULL)); if (!sub_dir_p (dst_file, spool->dest_dir)) @@ -230,10 +230,10 @@ void wydawca_lock_init () { if (enable_locking) { if (!lockdir) lockdir = xstrdup (LOCALSTATEDIR "/lock/" PACKAGE); - if (create_hierarchy (lockdir, 0, getuid (), getgid ())) + if (create_hierarchy (lockdir, 0)) exit (EX_OSFILE); } } @@ -332,13 +332,13 @@ do_notify (struct file_triplet *trp, enum notification_event ev, { mu_address_t rcpt = NULL; char *errp; switch (ntf->tgt) { case notify_admin: - rcpt = admin_address; + rcpt = mu_address_dup (admin_address); break; case notify_user: rcpt = get_recipient (trp->spool->access_method[user_data_method], trp, &errp); break; diff --git a/src/triplet.c b/src/triplet.c index 614e2b5..e060089 100644 --- a/src/triplet.c +++ b/src/triplet.c @@ -196,17 +196,13 @@ triplet_processor (void *data, void *proc_data) switch (check_triplet_state (trp)) { case triplet_directive: case triplet_complete: if (debug_level) logmsg (LOG_DEBUG, _("processing triplet `%s'"), trp->name); - if (wydawca_set_triplet_privs (trp) == 0) - { - process_directives (trp, spool); - wydawca_set_root_privs (); - } + process_directives (trp, spool); return true; case triplet_incomplete: if (debug_level) logmsg (LOG_DEBUG, _("%s: incomplete triplet"), trp->name); /* ignore unless expired (see below); */ diff --git a/src/userprivs.c b/src/userprivs.c new file mode 100644 index 0000000..e6a18c8 --- /dev/null +++ b/src/userprivs.c @@ -0,0 +1,118 @@ +/* wydawca - automatic release submission daemon + Copyright (C) 2007, 2009 Sergey Poznyakoff + + Wydawca 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. + + Wydawca 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 wydawca. If not, see <http://www.gnu.org/licenses/>. */ + +#include "wydawca.h" + +int +wydawca_userprivs (uid_t uid, gid_t gid, gid_t *grplist, size_t ngrp) +{ + int rc = 0; + size_t size = 1, j = 1; + + if (uid == 0) + return 0; + + /* Reset group permissions */ + if (geteuid () == 0 && setgroups (ngrp, grplist)) + { + logmsg (LOG_CRIT, "setgroups(%lu, %lu...): %s", + ngrp, grplist[0], 0, strerror (errno)); + return rc; + } + + /* Switch to the user's gid. On some OSes the effective gid must + be reset first */ + +#if defined(HAVE_SETEGID) + if ((rc = setegid (gid)) < 0) + logmsg (LOG_CRIT, "setegid(%lu): %s", gid, strerror (errno)); +#elif defined(HAVE_SETREGID) + if ((rc = setregid (gid, gid)) < 0) + logmsg (LOG_CRIT, "setregid(%lu,%lu)d: %s", + (unsigned long) gid, (unsigned long) gid, strerror (errno)); +#elif defined(HAVE_SETRESGID) + if ((rc = setresgid (gid, gid, gid)) < 0) + logmsg (LOG_CRIT, "setresgid(%lu,%lu,%lu): %s", + (unsigned long) gid, (unsigned long) gid, + (unsigned long) gid, + strerror (errno)); +#endif + + if (rc == 0 && gid != 0) + { + if ((rc = setgid (gid)) < 0 && getegid () != gid) + logmsg (LOG_CRIT, "setgid(%lu): %s", + (unsigned long) gid, strerror (errno)); + if (rc == 0 && getegid () != gid) + { + logmsg (LOG_CRIT, _("cannot set effective gid to %lu"), + (unsigned long) gid); + rc = 1; + } + } + + /* Now reset uid */ + if (rc == 0 && uid != 0) + { + uid_t euid; + + if (setuid (uid) + || geteuid () != uid + || (getuid () != uid + && (geteuid () == 0 || getuid () == 0))) + { + +#if defined(HAVE_SETREUID) + if (geteuid () != uid) + { + if (setreuid (uid, -1) < 0) + { + logmsg (LOG_CRIT, "setreuid(%lu,-1): %s", + (unsigned long) uid, strerror (errno)); + rc = 1; + } + if (setuid (uid) < 0) + { + logmsg (LOG_CRIT, "setreuid(%lu,-1): %s", + (unsigned long) uid, strerror (errno)); + rc = 1; + } + } + else +#endif + { + logmsg (LOG_CRIT, "setuid(%lu): %s", + (unsigned long) uid, strerror (errno)); + rc = 1; + } + } + + euid = geteuid (); + if (uid != 0 && setuid (0) == 0) + { + logmsg (LOG_CRIT, _("seteuid(0) succeeded when it should not")); + rc = 1; + } + else if (uid != euid && setuid (euid) == 0) + { + logmsg (LOG_CRIT, _("cannot drop non-root setuid privileges")); + rc = 1; + } + + } + + return rc; +} diff --git a/src/wydawca.c b/src/wydawca.c index 48c27e9..f02ac99 100644 --- a/src/wydawca.c +++ b/src/wydawca.c @@ -16,12 +16,16 @@ #include "wydawca.h" #include "mail.h" #include "argmatch.h" #include "version-etc.h" +uid_t wydawca_uid; +gid_t wydawca_gid; +size_t wydawca_supp_groupc; +gid_t *wydawca_supp_groups; char *conffile = SYSCONFDIR "/wydawca.rc" ; int debug_level; int dry_run_mode; int log_to_stderr = -1; /* -1 means autodetect */ int log_facility = LOG_LOCAL1; char *syslog_tag = "wydawca"; @@ -262,79 +266,12 @@ collect_uids (int argc, char **argv) else uidv[i] = pw->pw_uid; } } -static int -wydawca_set_uid (uid_t uid) -{ - int rc; - - if (getuid () != 0) - return 0; -#if defined(HAVE_SETREUID) - rc = setreuid (0, uid); -#elif defined(HAVE_SETRESUID) - rc = setresuid (-1, uid, -1); -#elif defined(HAVE_SETEUID) - rc = seteuid (uid); -#else -# error "No way to reset user privileges?" -#endif - if (rc < 0) - logmsg (LOG_ERR, _("cannot switch to UID %d: %s (r=%d, e=%d)"), - uid, strerror (errno), getuid (), geteuid ()); - return rc; -} - -static int -wydawca_set_gid (gid_t gid) -{ - int rc; - - if (getuid () != 0) - return 0; -#if defined(HAVE_SETREGID) - rc = setregid (0, gid); -#elif defined(HAVE_SETRESGID) - rc = setresgid (-1, gid, -1); -#elif defined(HAVE_SETEGID) - rc = setegid (gid); -#else -# error "No way to reset user privileges?" -#endif - if (rc < 0) - logmsg (LOG_ERR, _("cannot switch to GID %d: %s (r=%d, e=%d)"), - gid, strerror (errno), getgid (), getegid ()); - return rc; -} - -int -wydawca_set_privs (uid_t uid, gid_t gid) -{ - if (wydawca_set_gid (gid)) - return -1; - if (wydawca_set_uid (uid)) - return -1; - return 0; -} - -int -wydawca_set_triplet_privs (struct file_triplet *trp) -{ - return wydawca_set_privs (TRIPLET_UID (trp), TRIPLET_GID (trp)); -} - -int -wydawca_set_root_privs () -{ - return wydawca_set_privs (0, 0); -} - - char **x_argv; extern int reconfigure; void wydawca_daemon () { @@ -374,12 +311,14 @@ main (int argc, char **argv) if (gconf_parse (conffile)) exit (EX_CONFIG); if (lint_mode) exit (0); + if (dry_run_mode) + cron_option = 1; if (cron_option) daemon_mode = 0; if (foreground_option >= 0) foreground = foreground_option; if (single_process_option >= 0) single_process = single_process_option; @@ -391,12 +330,28 @@ main (int argc, char **argv) if (!log_to_stderr) { openlog (syslog_tag, LOG_PID, log_facility); log_printer = syslog_printer; } + if (getgid () == 0) + { + if (wydawca_uid == 0) + { + if (!force_startup) + { + logmsg (LOG_CRIT, _("won't run with root privileges")); + exit (EX_UNAVAILABLE); + } + } + else if (wydawca_userprivs (wydawca_uid, wydawca_gid, + wydawca_supp_groups, + wydawca_supp_groupc)) + exit (EX_UNAVAILABLE); + } + mail_init (); wydawca_lock_init (); logmsg (LOG_NOTICE, _("wydawca (%s) started"), PACKAGE_STRING); if (!daemon_mode) @@ -411,13 +366,12 @@ main (int argc, char **argv) mail_finish (); if (reconfigure) { int i; - wydawca_set_uid (0); for (i = getdtablesize (); i > 2; i--) close (i); remove_pidfile (); execv (x_argv[0], x_argv); } diff --git a/src/wydawca.h b/src/wydawca.h index f786271..81e6509 100644 --- a/src/wydawca.h +++ b/src/wydawca.h @@ -300,12 +300,16 @@ void meta_escape (struct access_method *method, void *handle, void meta_free (struct metadef *def); void make_default_meta (struct metadef kwexp[5], const char *user, const char *project); /* Global variables */ +extern uid_t wydawca_uid; +extern gid_t wydawca_gid; +extern size_t wydawca_supp_groupc; +extern gid_t *wydawca_supp_groups; extern char *conffile; /* Configuration file name */ extern int debug_level; /* Debugging level */ extern int dry_run_mode; /* Dry run indicator */ extern int log_to_stderr; /* Log to stderr instead of the syslog */ extern int log_facility; /* Syslog facility to use if !log_to_stderr */ extern char *syslog_tag; /* Syslog tag */ @@ -352,14 +356,14 @@ void logstats (void); char *safe_file_name (char *file_name); char *safe_file_name_alloc (const char *file_name); size_t trim_length (const char *str); size_t trim (char *str); void logmsg (int prio, char *fmt, ...) GSC_PRINTFLIKE(2,3); int test_dir (const char *name, int *ec); -char *create_directory (const char *base, const char *name, - uid_t uid, gid_t gid); +char *create_directory (const char *base, const char *name); +int create_hierarchy (char *dir, size_t baselen); void parse_config (void); void log_output (int prio, const char *prog, FILE *fp); enum exec_result { exec_success, /* Command executed and returned 0 */ @@ -425,15 +429,12 @@ int directive_next (struct file_triplet *trp, int n, const char **pkey, const char **pval); int process_directives (struct file_triplet *trp, const struct spool *spool); int enabled_spool_p (const struct spool *spool); -int wydawca_set_privs (uid_t uid, gid_t gid); -int wydawca_set_triplet_privs (struct file_triplet *trp); -int wydawca_set_root_privs (void); int parse_time_interval (const char *str, time_t *pint, const char **endp); /* config.c */ @@ -535,6 +536,9 @@ void wydawca_unlock (const char *lockname); void wydawca_lock_init (void); /* tcpwrap.h */ extern struct gconf_keyword tcpwrapper_kw[]; int tcpwrap_access(int fd); + +/* userprivs.c */ +int wydawca_userprivs (uid_t uid, gid_t gid, gid_t *grplist, size_t ngrp); |