diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-02-26 00:50:24 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-02-26 00:50:24 +0200 |
commit | 81640ab2b9ad954d4952aed43a70d7874da1c463 (patch) | |
tree | 8160066cb7259357f17a40121f7ed7d0fff5701e /src | |
parent | 9ec721b2a3a023f6339fe3c910635e477e4a311f (diff) | |
download | wydawca-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.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 | |||
@@ -38,2 +38,3 @@ wydawca_SOURCES=\ | |||
38 | triplet.c\ | 38 | triplet.c\ |
39 | userprivs.c\ | ||
39 | verify.c\ | 40 | verify.c\ |
diff --git a/src/config.c b/src/config.c index b1f339f..b6e2533 100644 --- a/src/config.c +++ b/src/config.c | |||
@@ -980,2 +980,3 @@ cb_access_method_params (enum gconf_callback_command cmd, | |||
980 | } | 980 | } |
981 | gl_list_iterator_free (&itr); | ||
981 | meth->parmv[i] = NULL; | 982 | meth->parmv[i] = NULL; |
@@ -1226,2 +1227,78 @@ cb_spool (enum gconf_callback_command cmd, | |||
1226 | 1227 | ||
1228 | static int | ||
1229 | cb_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 | |||
1253 | static int | ||
1254 | cb_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 | ||
@@ -1239,2 +1316,7 @@ static struct gconf_keyword wydawca_kw[] = { | |||
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"), |
diff --git a/src/directive.c b/src/directive.c index 2915fee..416095f 100644 --- a/src/directive.c +++ b/src/directive.c | |||
@@ -339,5 +339,3 @@ process_directives (struct file_triplet *trp, const struct spool *spool) | |||
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) |
diff --git a/src/diskio.c b/src/diskio.c index fbd1050..35ba71e 100644 --- a/src/diskio.c +++ b/src/diskio.c | |||
@@ -60,5 +60,5 @@ concat_dir (const char *base, const char *name, size_t *pbaselen) | |||
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. */ |
62 | int | 62 | int |
63 | create_hierarchy (char *dir, size_t baselen, uid_t uid, gid_t gid) | 63 | create_hierarchy (char *dir, size_t baselen) |
64 | { | 64 | { |
@@ -94,3 +94,3 @@ create_hierarchy (char *dir, size_t baselen, uid_t uid, gid_t gid) | |||
94 | 94 | ||
95 | rc = create_hierarchy (dir, baselen, uid, gid); | 95 | rc = create_hierarchy (dir, baselen); |
96 | if (rc == 0) | 96 | if (rc == 0) |
@@ -105,7 +105,2 @@ create_hierarchy (char *dir, size_t baselen, uid_t uid, gid_t gid) | |||
105 | } | 105 | } |
106 | if (chown (dir, uid, gid)) | ||
107 | { | ||
108 | logmsg (LOG_NOTICE, _("cannot change ownership of %s: %s"), | ||
109 | dir, strerror (errno)); | ||
110 | } | ||
111 | } | 106 | } |
@@ -118,3 +113,3 @@ create_hierarchy (char *dir, size_t baselen, uid_t uid, gid_t gid) | |||
118 | char * | 113 | char * |
119 | create_directory (const char *base, const char *name, uid_t uid, gid_t gid) | 114 | create_directory (const char *base, const char *name) |
120 | { | 115 | { |
@@ -125,7 +120,3 @@ create_directory (const char *base, const char *name, uid_t uid, gid_t gid) | |||
125 | { | 120 | { |
126 | int rc; | 121 | if (create_hierarchy (dir, baselen)) |
127 | wydawca_set_root_privs (); | ||
128 | rc = create_hierarchy (dir, baselen, uid, gid); | ||
129 | wydawca_set_privs (uid, gid); | ||
130 | if (rc) | ||
131 | { | 122 | { |
@@ -139,5 +130,5 @@ create_directory (const char *base, const char *name, uid_t uid, gid_t gid) | |||
139 | 130 | ||
140 | /* Copy FILE to DST_FILE, creating the latter with owner UID and GID. */ | 131 | /* Copy FILE to DST_FILE. */ |
141 | int | 132 | int |
142 | copy_file (const char *file, const char *dst_file, uid_t uid, gid_t gid) | 133 | copy_file (const char *file, const char *dst_file) |
143 | { | 134 | { |
@@ -225,6 +216,5 @@ copy_file (const char *file, const char *dst_file, uid_t uid, gid_t gid) | |||
225 | /* Move FILE to DST_FILE. If they reside on different devices, use copy_file | 216 | /* Move FILE to DST_FILE. If they reside on different devices, use copy_file |
226 | + unlink. | 217 | + unlink. */ |
227 | UID and GID give DST_FILE ownership. */ | ||
228 | int | 218 | int |
229 | do_move_file (const char *file, const char *dst_file, uid_t uid, gid_t gid) | 219 | do_move_file (const char *file, const char *dst_file) |
230 | { | 220 | { |
@@ -236,3 +226,3 @@ do_move_file (const char *file, const char *dst_file, uid_t uid, gid_t gid) | |||
236 | { | 226 | { |
237 | if (copy_file (file, dst_file, uid, gid)) | 227 | if (copy_file (file, dst_file)) |
238 | { | 228 | { |
@@ -301,3 +291,2 @@ tar_append_file (const char *archive, const char *file) | |||
301 | ARCHIVE - Archive descriptor. | 291 | ARCHIVE - Archive descriptor. |
302 | UID, GID - Ownership | ||
303 | RELDIR - Directory part of FILE | 292 | RELDIR - Directory part of FILE |
@@ -307,3 +296,3 @@ int | |||
307 | backup_file (const char *dst_file, const char *dst_dir, const char *file, | 296 | backup_file (const char *dst_file, const char *dst_dir, const char *file, |
308 | const struct archive_descr *archive, uid_t uid, gid_t gid, | 297 | const struct archive_descr *archive, |
309 | const char *reldir) | 298 | const char *reldir) |
@@ -315,5 +304,5 @@ backup_file (const char *dst_file, const char *dst_dir, const char *file, | |||
315 | if (archive->name[0] == '/') | 304 | if (archive->name[0] == '/') |
316 | adir = create_directory (archive->name, reldir, uid, gid); | 305 | adir = create_directory (archive->name, reldir); |
317 | else | 306 | else |
318 | adir = create_directory (dst_dir, archive->name, uid, gid); | 307 | adir = create_directory (dst_dir, archive->name); |
319 | if (!adir) | 308 | if (!adir) |
@@ -349,3 +338,3 @@ backup_file (const char *dst_file, const char *dst_dir, const char *file, | |||
349 | { | 338 | { |
350 | rc = do_move_file (file_name, archive_file_name, uid, gid); | 339 | rc = do_move_file (file_name, archive_file_name); |
351 | if (rc) | 340 | if (rc) |
@@ -368,3 +357,3 @@ backup_file (const char *dst_file, const char *dst_dir, const char *file, | |||
368 | { | 357 | { |
369 | rc = do_move_file (dst_file, file_name, uid, gid); | 358 | rc = do_move_file (dst_file, file_name); |
370 | if (rc) | 359 | if (rc) |
@@ -382,3 +371,3 @@ int | |||
382 | do_archive_file (const char *dst_file, const char *dst_dir, const char *file, | 371 | do_archive_file (const char *dst_file, const char *dst_dir, const char *file, |
383 | const struct archive_descr *archive, uid_t uid, gid_t gid, | 372 | const struct archive_descr *archive, |
384 | const char *reldir) | 373 | const char *reldir) |
@@ -391,3 +380,3 @@ do_archive_file (const char *dst_file, const char *dst_dir, const char *file, | |||
391 | case archive_directory: | 380 | case archive_directory: |
392 | return backup_file (dst_file, dst_dir, file, archive, uid, gid, reldir); | 381 | return backup_file (dst_file, dst_dir, file, archive, reldir); |
393 | 382 | ||
@@ -417,4 +406,3 @@ dir_move_file (struct file_triplet *trp, const struct spool *spool, | |||
417 | int rc = 0; | 406 | int rc = 0; |
418 | char *dst_dir = create_directory (spool->dest_dir, reldir, | 407 | char *dst_dir = create_directory (spool->dest_dir, reldir); |
419 | TRIPLET_UID (trp), TRIPLET_GID (trp)); | ||
420 | 408 | ||
@@ -430,8 +418,6 @@ dir_move_file (struct file_triplet *trp, const struct spool *spool, | |||
430 | rc = do_archive_file (dst_file, dst_dir, trp->file[file_id].name, | 418 | rc = do_archive_file (dst_file, dst_dir, trp->file[file_id].name, |
431 | &spool->archive, | 419 | &spool->archive, reldir); |
432 | TRIPLET_UID (trp), TRIPLET_GID (trp), reldir); | ||
433 | 420 | ||