aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-02-26 00:50:24 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2009-02-26 00:50:24 +0200
commit81640ab2b9ad954d4952aed43a70d7874da1c463 (patch)
tree8160066cb7259357f17a40121f7ed7d0fff5701e /src
parent9ec721b2a3a023f6339fe3c910635e477e4a311f (diff)
downloadwydawca-81640ab2b9ad954d4952aed43a70d7874da1c463.tar.gz
wydawca-81640ab2b9ad954d4952aed43a70d7874da1c463.tar.bz2
Switch to non-privileged UID/GID before startup.
* src/userprivs.c: New file. * src/Makefile.am (wydawca_SOURCES): Add userprivs.c * src/config.c (cb_access_method_params): Add missing gl_list_iterator_free. (cb_user, cb_supp_groups): New callbacks. (wydawca_kw): New keywords: user and group. * src/wydawca.c (wydawca_uid, wydawca_gid) (wydawca_supp_groupc, wydawca_supp_groups): New variables. (wydawca_set_uid, wydawca_set_gid, wydawca_set_privs) (wydawca_set_triplet_privs, wydawca_set_root_privs): Remove. (main): --dry-run implies --cron. Switch to non-privileged UID/GID before startup. * src/wydawca.h (wydawca_uid, wydawca_gid) (wydawca_supp_groupc, wydawca_supp_groups): New declarations. * src/mail.c (do_notify): Duplicate admin_address, it gets freed in do_notify. * src/directive.c, src/diskio.c, src/lock.c, src/triplet.c: Update.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/config.c82
-rw-r--r--src/directive.c2
-rw-r--r--src/diskio.c68
-rw-r--r--src/lock.c2
-rw-r--r--src/mail.c2
-rw-r--r--src/triplet.c6
-rw-r--r--src/userprivs.c118
-rw-r--r--src/wydawca.c90
-rw-r--r--src/wydawca.h14
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=\
33 pidfile.c\ 33 pidfile.c\
34 process.c\ 34 process.c\
35 sql.c\ 35 sql.c\
36 sql.h\ 36 sql.h\
37 tcpwrap.c\ 37 tcpwrap.c\
38 triplet.c\ 38 triplet.c\
39 userprivs.c\
39 verify.c\ 40 verify.c\
40 wydawca.c\ 41 wydawca.c\
41 wydawca.h\ 42 wydawca.h\
42 mail.h\ 43 mail.h\
43 mail.c\ 44 mail.c\
44 vtab.c\ 45 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,
975 975
976 if (assert_string_arg (locus, cmd, vp)) 976 if (assert_string_arg (locus, cmd, vp))
977 break; 977 break;
978 978
979 meth->parmv[i] = xstrdup (vp->v.string); 979 meth->parmv[i] = xstrdup (vp->v.string);
980 } 980 }
981 gl_list_iterator_free (&itr);
981 meth->parmv[i] = NULL; 982 meth->parmv[i] = NULL;
982 } 983 }
983 return 0; 984 return 0;
984} 985}
985 986
986static struct gconf_keyword access_method_kw[] = { 987static struct gconf_keyword access_method_kw[] = {
@@ -1221,12 +1222,88 @@ cb_spool (enum gconf_callback_command cmd,
1221 gconf_error (locus, 0, _("invalid use of block statement")); 1222 gconf_error (locus, 0, _("invalid use of block statement"));
1222 } 1223 }
1223 return 0; 1224 return 0;
1224} 1225}
1225 1226
1226 1227
1228static int
1229cb_user (enum gconf_callback_command cmd,
1230 gconf_locus_t *locus,
1231 void *varptr,
1232 gconf_value_t *value,
1233 void *cb_data)
1234{
1235 int rc;
1236 struct passwd *pw;
1237
1238 if (assert_string_arg (locus, cmd, value))
1239 return 1;
1240
1241 pw = getpwnam (value->v.string);
1242 if (!pw)
1243 {
1244 gconf_error (locus, 0, _("no such user: %s"), value->v.string);
1245 return 1;
1246 }
1247
1248 wydawca_uid = pw->pw_uid;
1249 wydawca_gid = pw->pw_gid;
1250 return 0;
1251}
1252
1253static int
1254cb_supp_groups (enum gconf_callback_command cmd,
1255 gconf_locus_t *locus,
1256 void *varptr,
1257 gconf_value_t *value,
1258 void *cb_data)
1259{
1260 if (cmd != gconf_callback_set_value)
1261 {
1262 gconf_error (locus, 0, _("Unexpected block statement"));
1263 return 1;
1264 }
1265 if (!value || value->type != GCONF_TYPE_LIST)
1266 {
1267 gconf_error (locus, 0, _("expected list value"));
1268 return 1;
1269 }
1270
1271 wydawca_supp_groupc = gl_list_size (value->v.list);
1272 if (wydawca_supp_groupc == 0)
1273 wydawca_supp_groups = NULL;
1274 else
1275 {
1276 int i;
1277 gl_list_iterator_t itr;
1278 const void *p;
1279
1280 wydawca_supp_groups = xcalloc (wydawca_supp_groupc,
1281 sizeof (wydawca_supp_groups[0]));
1282 itr = gl_list_iterator (value->v.list);
1283 for (i = 0; gl_list_iterator_next (&itr, &p, NULL); i++)
1284 {
1285 const gconf_value_t *vp = p;
1286 struct group *grp;
1287
1288 if (assert_string_arg (locus, cmd, vp))
1289 break;
1290 grp = getgrnam (vp->v.string);
1291 if (!grp)
1292 {
1293 gconf_error (locus, 0, _("no such group: %s"), value->v.string);
1294 break;
1295 }
1296 wydawca_supp_groups[i] = grp->gr_gid;
1297 }
1298 gl_list_iterator_free (&itr);
1299 }
1300 return 0;
1301}
1302
1303
1227 1304
1228static struct gconf_keyword wydawca_kw[] = { 1305static struct gconf_keyword wydawca_kw[] = {
1229 { "daemon", NULL, N_("Enable daemon mode"), 1306 { "daemon", NULL, N_("Enable daemon mode"),
1230 gconf_type_bool, &daemon_mode }, 1307 gconf_type_bool, &daemon_mode },
1231 { "foreground", NULL, N_("Start in foreground even in daemon mode"), 1308 { "foreground", NULL, N_("Start in foreground even in daemon mode"),
1232 gconf_type_bool, &foreground }, 1309 gconf_type_bool, &foreground },
@@ -1234,12 +1311,17 @@ static struct gconf_keyword wydawca_kw[] = {
1234 gconf_type_bool, &single_process }, 1311 gconf_type_bool, &single_process },
1235 { "wakeup-interval", N_("time"), N_("Set wake-up interval"), 1312 { "wakeup-interval", N_("time"), N_("Set wake-up interval"),
1236 gconf_type_string, &wakeup_interval, 0, cb_interval }, 1313 gconf_type_string, &wakeup_interval, 0, cb_interval },
1237 { "pidfile", N_("file"), N_("Set pid file name"), 1314 { "pidfile", N_("file"), N_("Set pid file name"),
1238 gconf_type_string, &pidfile }, 1315 gconf_type_string, &pidfile },
1239 1316
1317 { "user", N_("name"), N_("Run with UID and GID of this user"),
1318 gconf_type_string, NULL, 0, cb_user },
1319 { "group", NULL, N_("Retain these supplementary groups"),
1320 gconf_type_string|GCONF_LIST, NULL, 0, cb_supp_groups },
1321
1240 { "locking", NULL, N_("Enable or disable locking"), 1322 { "locking", NULL, N_("Enable or disable locking"),
1241 gconf_type_bool, &enable_locking }, 1323 gconf_type_bool, &enable_locking },
1242 { "lockdir", N_("dir"), N_("Set directory for lock files"), 1324 { "lockdir", N_("dir"), N_("Set directory for lock files"),
1243 gconf_type_string, &lockdir }, 1325 gconf_type_string, &lockdir },
1244 { "lock-expire-time", N_("interval"), N_("Define lock expiration interval"), 1326 { "lock-expire-time", N_("interval"), N_("Define lock expiration interval"),
1245 gconf_type_string, &lock_expire_time, 0, cb_interval }, 1327 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)
334 trp->file[file_directive].name, val); 334 trp->file[file_directive].name, val);
335 return 1; 335 return 1;
336 } 336 }
337 break; 337 break;
338 338
339 case filename_dir: 339 case filename_dir:
340 wydawca_set_root_privs ();
341 rc = verify_detached_signature (trp, spool); 340 rc = verify_detached_signature (trp, spool);
342 wydawca_set_triplet_privs (trp);
343 if (rc == 0) 341 if (rc == 0)
344 { 342 {
345 if (move_file (trp, spool, file_dist, relative_dir) 343 if (move_file (trp, spool, file_dist, relative_dir)
346 || move_file (trp, spool, file_signature, relative_dir)) 344 || move_file (trp, spool, file_signature, relative_dir))
347 return 1; 345 return 1;
348 } 346 }
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)
55 if (pbaselen) 55 if (pbaselen)
56 *pbaselen = len; 56 *pbaselen = len;
57 return dir; 57 return dir;
58} 58}
59 59
60/* Create the directory DIR, eventually creating all intermediate directories 60/* Create the directory DIR, eventually creating all intermediate directories
61 starting from DIR + BASELEN, with owner UID and GID. */ 61 starting from DIR + BASELEN. */
62int 62int
63create_hierarchy (char *dir, size_t baselen, uid_t uid, gid_t gid) 63create_hierarchy (char *dir, size_t baselen)
64{ 64{
65 int rc; 65 int rc;
66 struct stat st; 66 struct stat st;
67 char *p; 67 char *p;
68 68
69 if (stat (dir, &st) == 0) 69 if (stat (dir, &st) == 0)
@@ -89,60 +89,51 @@ create_hierarchy (char *dir, size_t baselen, uid_t uid, gid_t gid)
89 logmsg (LOG_ERR, _("base directory %s does not exist"), dir); 89 logmsg (LOG_ERR, _("base directory %s does not exist"), dir);
90 return 1; 90 return 1;
91 } 91 }
92 *p = 0; 92 *p = 0;
93 } 93 }
94 94
95 rc = create_hierarchy (dir, baselen, uid, gid); 95 rc = create_hierarchy (dir, baselen);
96 if (rc == 0) 96 if (rc == 0)
97 { 97 {