~ubuntu-branches/ubuntu/trusty/rsync/trusty

« back to all changes in this revision

Viewing changes to clientserver.c

  • Committer: Package Import Robot
  • Author(s): Paul Slootman
  • Date: 2013-10-27 12:01:10 UTC
  • mfrom: (1.1.13) (2.1.11 sid)
  • Revision ID: package-import@ubuntu.com-20131027120110-mpr03n5scqmf40mi
Tags: 3.1.0-2
fix build failure if zlib1g-dev package is not installed;
solved by building without the included zlib source and adding a
build-depends on zlib1g-dev >= 1:1.2.8
closes:32379

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 *
4
4
 * Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
5
5
 * Copyright (C) 2001-2002 Martin Pool <mbp@samba.org>
6
 
 * Copyright (C) 2002-2009 Wayne Davison
 
6
 * Copyright (C) 2002-2013 Wayne Davison
7
7
 *
8
8
 * This program is free software; you can redistribute it and/or modify
9
9
 * it under the terms of the GNU General Public License as published by
20
20
 */
21
21
 
22
22
#include "rsync.h"
23
 
#include "ifuncs.h"
 
23
#include "itypes.h"
24
24
 
25
25
extern int quiet;
26
 
extern int verbose;
27
26
extern int dry_run;
28
27
extern int output_motd;
29
28
extern int list_only;
37
36
extern int preserve_xattrs;
38
37
extern int kluge_around_eof;
39
38
extern int daemon_over_rsh;
 
39
extern int munge_symlinks;
40
40
extern int sanitize_paths;
41
41
extern int numeric_ids;
42
42
extern int filesfrom_fd;
48
48
extern int default_af_hint;
49
49
extern int logfile_format_has_i;
50
50
extern int logfile_format_has_o_or_i;
51
 
extern mode_t orig_umask;
52
51
extern char *bind_address;
53
52
extern char *config_file;
54
53
extern char *logfile_format;
55
54
extern char *files_from;
56
55
extern char *tmpdir;
57
56
extern struct chmod_mode_struct *chmod_modes;
58
 
extern struct filter_list_struct daemon_filter_list;
 
57
extern filter_rule_list daemon_filter_list;
59
58
#ifdef ICONV_OPTION
60
59
extern char *iconv_opt;
61
60
extern iconv_t ic_send, ic_recv;
62
61
#endif
63
62
 
 
63
#define MAX_GID_LIST 32
 
64
 
64
65
char *auth_user;
65
66
int read_only = 0;
66
67
int module_id = -1;
67
 
int munge_symlinks = 0;
68
68
struct chmod_mode_struct *daemon_chmod_modes;
69
69
 
70
70
/* module_dirlen is the length of the module_dir string when in daemon
81
81
static struct sigaction sigact;
82
82
#endif
83
83
 
 
84
static gid_t gid_list[MAX_GID_LIST];
 
85
static int gid_count = 0;
 
86
 
 
87
/* Used when "reverse lookup" is off. */
 
88
const char undetermined_hostname[] = "UNDETERMINED";
 
89
 
84
90
/**
85
91
 * Run a client connected to an rsyncd.  The alternative to this
86
92
 * function for remote-shell connections is do_cmd().
158
164
        }
159
165
 
160
166
        /* This strips the \n. */
161
 
        if (!read_line_old(f_in, buf, bufsiz)) {
 
167
        if (!read_line_old(f_in, buf, bufsiz, 0)) {
162
168
                if (am_client)
163
169
                        rprintf(FERROR, "rsync: did not see server greeting\n");
164
170
                return -1;
270
276
 
271
277
        sargs[sargc] = NULL;
272
278
 
273
 
        if (verbose > 1)
 
279
        if (DEBUG_GTE(CMD, 1))
274
280
                print_child_argv("sending daemon args:", sargs);
275
281
 
276
282
        io_printf(f_out, "%.*s\n", modlen, modname);
280
286
        kluge_around_eof = list_only && protocol_version < 25 ? 1 : 0;
281
287
 
282
288
        while (1) {
283
 
                if (!read_line_old(f_in, line, sizeof line)) {
 
289
                if (!read_line_old(f_in, line, sizeof line, 0)) {
284
290
                        rprintf(FERROR, "rsync: didn't get server startup line\n");
285
291
                        return -1;
286
292
                }
334
340
 
335
341
        if (protocol_version < 23) {
336
342
                if (protocol_version == 22 || !am_sender)
337
 
                        io_start_multiplex_in();
 
343
                        io_start_multiplex_in(f_in);
338
344
        }
339
345
 
340
346
        free(modname);
342
348
        return 0;
343
349
}
344
350
 
345
 
static char *finish_pre_exec(pid_t pid, int fd, char *request,
 
351
static char *finish_pre_exec(pid_t pid, int write_fd, int read_fd, char *request,
346
352
                             char **early_argv, char **argv)
347
353
{
348
 
        int j = 0, status = -1;
 
354
        char buf[BIGPATHBUFLEN], *bp;
 
355
        int j = 0, status = -1, msglen = sizeof buf - 1;
349
356
 
350
357
        if (!request)
351
358
                request = "(NONE)";
352
359
 
353
 
        write_buf(fd, request, strlen(request)+1);
 
360
        write_buf(write_fd, request, strlen(request)+1);
354
361
        if (early_argv) {
355
362
                for ( ; *early_argv; early_argv++)
356
 
                        write_buf(fd, *early_argv, strlen(*early_argv)+1);
 
363
                        write_buf(write_fd, *early_argv, strlen(*early_argv)+1);
357
364
                j = 1; /* Skip arg0 name in argv. */
358
365
        }
359
 
        for ( ; argv[j]; j++) {
360
 
                write_buf(fd, argv[j], strlen(argv[j])+1);
361
 
                if (argv[j][0] == '.' && argv[j][1] == '\0')
362
 
                        break;
 
366
        for ( ; argv[j]; j++)
 
367
                write_buf(write_fd, argv[j], strlen(argv[j])+1);
 
368
        write_byte(write_fd, 0);
 
369
 
 
370
        close(write_fd);
 
371
 
 
372
        /* Read the stdout from the pre-xfer exec program.  This it is only
 
373
         * displayed to the user if the script also returns an error status. */
 
374
        for (bp = buf; msglen > 0; msglen -= j) {
 
375
                if ((j = read(read_fd, bp, msglen)) <= 0) {
 
376
                        if (j == 0)
 
377
                                break;
 
378
                        if (errno == EINTR)
 
379
                                continue;
 
380
                        break; /* Just ignore the read error for now... */
 
381
                }
 
382
                bp += j;
 
383
                if (j > 1 && bp[-1] == '\n' && bp[-2] == '\r') {
 
384
                        bp--;
 
385
                        j--;
 
386
                        bp[-1] = '\n';
 
387
                }
363
388
        }
364
 
        write_byte(fd, 0);
 
389
        *bp = '\0';
365
390
 
366
 
        close(fd);
 
391
        close(read_fd);
367
392
 
368
393
        if (wait_process(pid, &status, 0) < 0
369
394
         || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
370
395
                char *e;
371
 
                if (asprintf(&e, "pre-xfer exec returned failure (%d)%s%s\n",
 
396
                if (asprintf(&e, "pre-xfer exec returned failure (%d)%s%s%s\n%s",
372
397
                             status, status < 0 ? ": " : "",
373
 
                             status < 0 ? strerror(errno) : "") < 0)
374
 
                        out_of_memory("finish_pre_exec");
 
398
                             status < 0 ? strerror(errno) : "",
 
399
                             *buf ? ":" : "", buf) < 0)
 
400
                        return "out_of_memory in finish_pre_exec\n";
375
401
                return e;
376
402
        }
377
403
        return NULL;
378
404
}
379
405
 
 
406
#ifdef HAVE_PUTENV
380
407
static int read_arg_from_pipe(int fd, char *buf, int limit)
381
408
{
382
409
        char *bp = buf, *eob = buf + limit - 1;
383
410
 
384
411
        while (1) {
385
 
            int got = read(fd, bp, 1);
386
 
            if (got != 1) {
387
 
                if (got < 0 && errno == EINTR)
388
 
                        continue;
389
 
                return -1;
390
 
            }
391
 
            if (*bp == '\0')
392
 
                break;
393
 
            if (bp < eob)
394
 
                bp++;
 
412
                int got = read(fd, bp, 1);
 
413
                if (got != 1) {
 
414
                        if (got < 0 && errno == EINTR)
 
415
                                continue;
 
416
                        return -1;
 
417
                }
 
418
                if (*bp == '\0')
 
419
                        break;
 
420
                if (bp < eob)
 
421
                        bp++;
395
422
        }
396
423
        *bp = '\0';
397
424
 
398
425
        return bp - buf;
399
426
}
 
427
#endif
400
428
 
401
429
static int path_failure(int f_out, const char *dir, BOOL was_chdir)
402
430
{
408
436
        return -1;
409
437
}
410
438
 
411
 
static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
 
439
static int add_a_group(int f_out, const char *gname)
 
440
{
 
441
        gid_t gid;
 
442
        if (!group_to_gid(gname, &gid, True)) {
 
443
                rprintf(FLOG, "Invalid gid %s\n", gname);
 
444
                io_printf(f_out, "@ERROR: invalid gid %s\n", gname);
 
445
                return -1;
 
446
        }
 
447
        if (gid_count == MAX_GID_LIST) {
 
448
                rprintf(FLOG, "Too many groups specified via gid parameter.\n");
 
449
                io_printf(f_out, "@ERROR: too many groups\n");
 
450
                return -1;
 
451
        }
 
452
        gid_list[gid_count++] = gid;
 
453
        return 0;
 
454
}
 
455
 
 
456
#ifdef HAVE_GETGROUPLIST
 
457
static int want_all_groups(int f_out, uid_t uid)
 
458
{
 
459
        const char *err;
 
460
        gid_count = MAX_GID_LIST;
 
461
        if ((err = getallgroups(uid, gid_list, &gid_count)) != NULL) {
 
462
                rsyserr(FLOG, errno, "%s", err);
 
463
                io_printf(f_out, "@ERROR: %s\n", err);
 
464
                return -1;
 
465
        }
 
466
        return 0;
 
467
}
 
468
#elif defined HAVE_INITGROUPS
 
469
static struct passwd *want_all_groups(int f_out, uid_t uid)
 
470
{
 
471
        struct passwd *pw;
 
472
        if ((pw = getpwuid(uid)) == NULL) {
 
473
                rsyserr(FLOG, errno, "getpwuid failed");
 
474
                io_printf(f_out, "@ERROR: getpwuid failed\n");
 
475
                return NULL;
 
476
        }
 
477
        /* Start with the default group and initgroups() will add the reset. */
 
478
        gid_count = 1;
 
479
        gid_list[0] = pw->pw_gid;
 
480
        return pw;
 
481
}
 
482
#endif
 
483
 
 
484
static void set_env_str(const char *var, const char *str)
 
485
{
 
486
#ifdef HAVE_PUTENV
 
487
        char *mem;
 
488
        if (asprintf(&mem, "%s=%s", var, str) < 0)
 
489
                out_of_memory("set_env_str");
 
490
        putenv(mem);
 
491
#endif
 
492
}
 
493
 
 
494
#ifdef HAVE_PUTENV
 
495
static void set_env_num(const char *var, long num)
 
496
{
 
497
        char *mem;
 
498
        if (asprintf(&mem, "%s=%ld", var, num) < 0)
 
499
                out_of_memory("set_env_num");
 
500
        putenv(mem);
 
501
}
 
502
#endif
 
503
 
 
504
static int rsync_module(int f_in, int f_out, int i, const char *addr, const char *host)
412
505
{
413
506
        int argc;
414
507
        char **argv, **orig_argv, **orig_early_argv, *module_chdir;
415
508
        char line[BIGPATHBUFLEN];
416
 
        uid_t uid = (uid_t)-2;  /* canonically "nobody" */
417
 
        gid_t gid = (gid_t)-2;
 
509
#if defined HAVE_INITGROUPS && !defined HAVE_GETGROUPLIST
 
510
        struct passwd *pw = NULL;
 
511
#endif
 
512
        uid_t uid;
 
513
        int set_uid;
418
514
        char *p, *err_msg = NULL;
419
515
        char *name = lp_name(i);
420
516
        int use_chroot = lp_use_chroot(i);
421
 
        int ret, pre_exec_fd = -1;
 
517
        int ret, pre_exec_arg_fd = -1, pre_exec_error_fd = -1;
 
518
        int save_munge_symlinks;
422
519
        pid_t pre_exec_pid = 0;
423
520
        char *request = NULL;
424
521
 
 
522
        set_env_str("RSYNC_MODULE_NAME", name);
 
523
 
425
524
#ifdef ICONV_OPTION
426
525
        iconv_opt = lp_charset(i);
427
526
        if (*iconv_opt)
429
528
        iconv_opt = NULL;
430
529
#endif
431
530
 
432
 
        if (!allow_access(addr, host, lp_hosts_allow(i), lp_hosts_deny(i))) {
 
531
        /* If reverse lookup is disabled globally but enabled for this module,
 
532
         * we need to do it now before the access check. */
 
533
        if (host == undetermined_hostname && lp_reverse_lookup(i))
 
534
                host = client_name(f_in);
 
535
        set_env_str("RSYNC_HOST_NAME", host);
 
536
        set_env_str("RSYNC_HOST_ADDR", addr);
 
537
 
 
538
        if (!allow_access(addr, &host, i)) {
433
539
                rprintf(FLOG, "rsync denied on module %s from %s (%s)\n",
434
540
                        name, host, addr);
435
541
                if (!lp_list(i))
461
567
                return -1;
462
568
        }
463
569
 
 
570
        read_only = lp_read_only(i); /* may also be overridden by auth_server() */
464
571
        auth_user = auth_server(f_in, f_out, i, host, addr, "@RSYNCD: AUTHREQD ");
465
572
 
466
573
        if (!auth_user) {
467
574
                io_printf(f_out, "@ERROR: auth failed on module %s\n", name);
468
575
                return -1;
469
576
        }
 
577
        set_env_str("RSYNC_USER_NAME", auth_user);
470
578
 
471
579
        module_id = i;
472
580
 
473
 
        if (lp_read_only(i))
474
 
                read_only = 1;
475
 
 
476
581
        if (lp_transfer_logging(i) && !logfile_format)
477
582
                logfile_format = lp_log_format(i);
478
583
        if (log_format_has(logfile_format, 'i'))
480
585
        if (logfile_format_has_i || log_format_has(logfile_format, 'o'))
481
586
                logfile_format_has_o_or_i = 1;
482
587
 
483
 
        am_root = (MY_UID() == 0);
484
 
 
485
 
        if (am_root) {
486
 
                p = lp_uid(i);
487
 
                if (!name_to_uid(p, &uid)) {
488
 
                        if (!isDigit(p)) {
489
 
                                rprintf(FLOG, "Invalid uid %s\n", p);
490
 
                                io_printf(f_out, "@ERROR: invalid uid %s\n", p);
491
 
                                return -1;
492
 
                        }
493
 
                        uid = atoi(p);
494
 
                }
495
 
 
496
 
                p = lp_gid(i);
497
 
                if (!name_to_gid(p, &gid)) {
498
 
                        if (!isDigit(p)) {
499
 
                                rprintf(FLOG, "Invalid gid %s\n", p);
500
 
                                io_printf(f_out, "@ERROR: invalid gid %s\n", p);
501
 
                                return -1;
502
 
                        }
503
 
                        gid = atoi(p);
504
 
                }
 
588
        uid = MY_UID();
 
589
        am_root = (uid == 0);
 
590
 
 
591
        p = *lp_uid(i) ? lp_uid(i) : am_root ? NOBODY_USER : NULL;
 
592
        if (p) {
 
593
                if (!user_to_uid(p, &uid, True)) {
 
594
                        rprintf(FLOG, "Invalid uid %s\n", p);
 
595
                        io_printf(f_out, "@ERROR: invalid uid %s\n", p);
 
596
                        return -1;
 
597
                }
 
598
                set_uid = 1;
 
599
        } else
 
600
                set_uid = 0;
 
601
 
 
602
        p = *lp_gid(i) ? strtok(lp_gid(i), ", ") : NULL;
 
603
        if (p) {
 
604
                /* The "*" gid must be the first item in the list. */
 
605
                if (strcmp(p, "*") == 0) {
 
606
#ifdef HAVE_GETGROUPLIST
 
607
                        if (want_all_groups(f_out, uid) < 0)
 
608
                                return -1;
 
609
#elif defined HAVE_INITGROUPS
 
610
                        if ((pw = want_all_groups(f_out, uid)) == NULL)
 
611
                                return -1;
 
612
#else
 
613
                        rprintf(FLOG, "This rsync does not support a gid of \"*\"\n");
 
614
                        io_printf(f_out, "@ERROR: invalid gid setting.\n");
 
615
                        return -1;
 
616
#endif
 
617
                } else if (add_a_group(f_out, p) < 0)
 
618
                        return -1;
 
619
                while ((p = strtok(NULL, ", ")) != NULL) {
 
620
#if defined HAVE_INITGROUPS && !defined HAVE_GETGROUPLIST
 
621
                        if (pw) {
 
622
                                rprintf(FLOG, "This rsync cannot add groups after \"*\".\n");
 
623
                                io_printf(f_out, "@ERROR: invalid gid setting.\n");
 
624
                                return -1;
 
625
                        }
 
626
#endif
 
627
                        if (add_a_group(f_out, p) < 0)
 
628
                                return -1;
 
629
                }
 
630
        } else if (am_root) {
 
631
                if (add_a_group(f_out, NOBODY_GROUP) < 0)
 
632
                        return -1;
505
633
        }
506
634
 
507
 
        /* TODO: If we're not root, but the configuration requests
508
 
         * that we change to some uid other than the current one, then
509
 
         * log a warning. */
510
 
 
511
 
        /* TODO: Perhaps take a list of gids, and make them into the
512
 
         * supplementary groups. */
513
 
 
514
635
        module_dir = lp_path(i);
515
636
        if (*module_dir == '\0') {
516
637
                rprintf(FLOG, "No path specified for module %s\n", name);
540
661
                        return path_failure(f_out, module_dir, False);
541
662
                full_module_path = module_dir = module_chdir;
542
663
        }
 
664
        set_env_str("RSYNC_MODULE_PATH", full_module_path);
543
665
 
544
666
        if (module_dirlen == 1) {
545
667
                module_dirlen = 0;
548
670
                set_filter_dir(module_dir, module_dirlen);
549
671
 
550
672
        p = lp_filter(i);
551
 
        parse_rule(&daemon_filter_list, p, MATCHFLG_WORD_SPLIT,
 
673
        parse_filter_str(&daemon_filter_list, p, rule_template(FILTRULE_WORD_SPLIT),
552
674
                   XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3);
553
675
 
554
676
        p = lp_include_from(i);
555
 
        parse_filter_file(&daemon_filter_list, p, MATCHFLG_INCLUDE,
 
677
        parse_filter_file(&daemon_filter_list, p, rule_template(FILTRULE_INCLUDE),
556
678
            XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS);
557
679
 
558
680
        p = lp_include(i);
559
 
        parse_rule(&daemon_filter_list, p,
560
 
                   MATCHFLG_INCLUDE | MATCHFLG_WORD_SPLIT,
 
681
        parse_filter_str(&daemon_filter_list, p,
 
682
                   rule_template(FILTRULE_INCLUDE | FILTRULE_WORD_SPLIT),
561
683
                   XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES);
562
684
 
563
685
        p = lp_exclude_from(i);
564
 
        parse_filter_file(&daemon_filter_list, p, 0,
 
686
        parse_filter_file(&daemon_filter_list, p, rule_template(0),
565
687
            XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS);
566
688
 
567
689
        p = lp_exclude(i);
568
 
        parse_rule(&daemon_filter_list, p, MATCHFLG_WORD_SPLIT,
 
690
        parse_filter_str(&daemon_filter_list, p, rule_template(FILTRULE_WORD_SPLIT),
569
691
                   XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES);
570
692
 
571
693
        log_init(1);
572
694
 
573
695
#ifdef HAVE_PUTENV
574
696
        if (*lp_prexfer_exec(i) || *lp_postxfer_exec(i)) {
575
 
                char *modname, *modpath, *hostaddr, *hostname, *username;
576
697
                int status;
577
698
 
578
 
                if (asprintf(&modname, "RSYNC_MODULE_NAME=%s", name) < 0
579
 
                 || asprintf(&modpath, "RSYNC_MODULE_PATH=%s", full_module_path) < 0
580
 
                 || asprintf(&hostaddr, "RSYNC_HOST_ADDR=%s", addr) < 0
581
 
                 || asprintf(&hostname, "RSYNC_HOST_NAME=%s", host) < 0
582
 
                 || asprintf(&username, "RSYNC_USER_NAME=%s", auth_user) < 0)
583
 
                        out_of_memory("rsync_module");
584
 
                putenv(modname);
585
 
                putenv(modpath);
586
 
                putenv(hostaddr);
587
 
                putenv(hostname);
588
 
                putenv(username);
589
 
                umask(orig_umask);
590
699
                /* For post-xfer exec, fork a new process to run the rsync
591
700
                 * daemon while this process waits for the exit status and
592
701
                 * runs the indicated command at that point. */
598
707
                                return -1;
599
708
                        }
600
709
                        if (pid) {
601
 
                                if (asprintf(&p, "RSYNC_PID=%ld", (long)pid) > 0)
602
 
                                        putenv(p);
 
710
                                close(f_in);
 
711
                                if (f_out != f_in)
 
712
                                        close(f_out);
 
713
                                set_env_num("RSYNC_PID", (long)pid);
603
714
                                if (wait_process(pid, &status, 0) < 0)
604
715
                                        status = -1;
605
 
                                if (asprintf(&p, "RSYNC_RAW_STATUS=%d", status) > 0)
606
 
                                        putenv(p);
 
716
                                set_env_num("RSYNC_RAW_STATUS", status);
607
717
                                if (WIFEXITED(status))
608
718
                                        status = WEXITSTATUS(status);
609
719
                                else
610
720
                                        status = -1;
611
 
                                if (asprintf(&p, "RSYNC_EXIT_STATUS=%d", status) > 0)
612
 
                                        putenv(p);
 
721
                                set_env_num("RSYNC_EXIT_STATUS", status);
613
722
                                if (system(lp_postxfer_exec(i)) < 0)
614
723
                                        status = -1;
615
724
                                _exit(status);
619
728
                 * command, though it first waits for the parent process to
620
729
                 * send us the user's request via a pipe. */
621
730
                if (*lp_prexfer_exec(i)) {
622
 
                        int fds[2];
623
 
                        if (asprintf(&p, "RSYNC_PID=%ld", (long)getpid()) > 0)
624
 
                                putenv(p);
625
 
                        if (pipe(fds) < 0 || (pre_exec_pid = fork()) < 0) {
 
731
                        int arg_fds[2], error_fds[2];
 
732
                        set_env_num("RSYNC_PID", (long)getpid());
 
733
                        if (pipe(arg_fds) < 0 || pipe(error_fds) < 0 || (pre_exec_pid = fork()) < 0) {
626
734
                                rsyserr(FLOG, errno, "pre-xfer exec preparation failed");
627
735
                                io_printf(f_out, "@ERROR: pre-xfer exec preparation failed\n");
628
736
                                return -1;
630
738
                        if (pre_exec_pid == 0) {
631
739
                                char buf[BIGPATHBUFLEN];
632
740
                                int j, len;
633
 
                                close(fds[1]);
634
 
                                set_blocking(fds[0]);
635
 
                                len = read_arg_from_pipe(fds[0], buf, BIGPATHBUFLEN);
 
741
                                close(arg_fds[1]);
 
742
                                close(error_fds[0]);
 
743
                                pre_exec_arg_fd = arg_fds[0];
 
744
                                pre_exec_error_fd = error_fds[1];
 
745
                                set_blocking(pre_exec_arg_fd);
 
746
                                set_blocking(pre_exec_error_fd);
 
747
                                len = read_arg_from_pipe(pre_exec_arg_fd, buf, BIGPATHBUFLEN);
636
748
                                if (len <= 0)
637
749
                                        _exit(1);
638
 
                                if (asprintf(&p, "RSYNC_REQUEST=%s", buf) > 0)
639
 
                                        putenv(p);
 
750
                                set_env_str("RSYNC_REQUEST", buf);
640
751
                                for (j = 0; ; j++) {
641
 
                                        len = read_arg_from_pipe(fds[0], buf,
 
752
                                        len = read_arg_from_pipe(pre_exec_arg_fd, buf,
642
753
                                                                 BIGPATHBUFLEN);
643
754
                                        if (len <= 0) {
644
755
                                                if (!len)
645
756
                                                        break;
646
757
                                                _exit(1);
647
758
                                        }
648
 
                                        if (asprintf(&p, "RSYNC_ARG%d=%s", j, buf) > 0)
 
759
                                        if (asprintf(&p, "RSYNC_ARG%d=%s", j, buf) >= 0)
649
760
                                                putenv(p);
650
761
                                }
651
 
                                close(fds[0]);
 
762
                                close(pre_exec_arg_fd);
652
763
                                close(STDIN_FILENO);
653
 
                                close(STDOUT_FILENO);
 
764
                                dup2(pre_exec_error_fd, STDOUT_FILENO);
 
765
                                close(pre_exec_error_fd);
654
766
                                status = system(lp_prexfer_exec(i));
655
767
                                if (!WIFEXITED(status))
656
768
                                        _exit(1);
657
769
                                _exit(WEXITSTATUS(status));
658
770
                        }
659
 
                        close(fds[0]);
660
 
                        set_blocking(fds[1]);
661
 
                        pre_exec_fd = fds[1];
 
771
                        close(arg_fds[0]);
 
772
                        close(error_fds[1]);
 
773
                        pre_exec_arg_fd = arg_fds[1];
 
774
                        pre_exec_error_fd = error_fds[0];
 
775
                        set_blocking(pre_exec_arg_fd);
 
776
                        set_blocking(pre_exec_error_fd);
662
777
                }
663
 
                umask(0);
664
778
        }
665
779
#endif
666
780
 
694
808
                munge_symlinks = !use_chroot || module_dirlen;
695
809
        if (munge_symlinks) {
696
810
                STRUCT_STAT st;
697
 
                if (do_stat(SYMLINK_PREFIX, &st) == 0 && S_ISDIR(st.st_mode)) {
698
 
                        rprintf(FLOG, "Symlink munging is unsupported when a %s directory exists.\n",
699
 
                                SYMLINK_PREFIX);
 
811
                char prefix[SYMLINK_PREFIX_LEN]; /* NOT +1 ! */
 
812
                strlcpy(prefix, SYMLINK_PREFIX, sizeof prefix); /* trim the trailing slash */
 
813
                if (do_stat(prefix, &st) == 0 && S_ISDIR(st.st_mode)) {
 
814
                        rprintf(FLOG, "Symlink munging is unsafe when a %s directory exists.\n",
 
815
                                prefix);
700
816
                        io_printf(f_out, "@ERROR: daemon security issue -- contact admin\n", name);
701
817
                        exit_cleanup(RERR_UNSUPPORTED);
702
818
                }
703
819
        }
704
820
 
705
 
        if (am_root) {
706
 
                /* XXXX: You could argue that if the daemon is started
707
 
                 * by a non-root user and they explicitly specify a
708
 
                 * gid, then we should try to change to that gid --
709
 
                 * this could be possible if it's already in their
710
 
                 * supplementary groups. */
711
 
 
712
 
                /* TODO: Perhaps we need to document that if rsyncd is
713
 
                 * started by somebody other than root it will inherit
714
 
                 * all their supplementary groups. */
715
 
 
716
 
                if (setgid(gid)) {
717
 
                        rsyserr(FLOG, errno, "setgid %d failed", (int)gid);
 
821
        if (gid_count) {
 
822
                if (setgid(gid_list[0])) {
 
823
                        rsyserr(FLOG, errno, "setgid %ld failed", (long)gid_list[0]);
718
824
                        io_printf(f_out, "@ERROR: setgid failed\n");
719
825
                        return -1;
720
826
                }
721
827
#ifdef HAVE_SETGROUPS
722
 
                /* Get rid of any supplementary groups this process
723
 
                 * might have inheristed. */
724
 
                if (setgroups(1, &gid)) {
 
828
                /* Set the group(s) we want to be active. */
 
829
                if (setgroups(gid_count, gid_list)) {
725
830
                        rsyserr(FLOG, errno, "setgroups failed");
726
831
                        io_printf(f_out, "@ERROR: setgroups failed\n");
727
832
                        return -1;
728
833
                }
729
834
#endif
 
835
#if defined HAVE_INITGROUPS && !defined HAVE_GETGROUPLIST
 
836
                /* pw is set if the user wants all the user's groups. */
 
837
                if (pw && initgroups(pw->pw_name, pw->pw_gid) < 0) {
 
838
                        rsyserr(FLOG, errno, "initgroups failed");
 
839
                        io_printf(f_out, "@ERROR: initgroups failed\n");
 
840
                        return -1;
 
841
                }
 
842
#endif
 
843
        }
730
844
 
 
845
        if (set_uid) {
731
846
                if (setuid(uid) < 0
732
847
#ifdef HAVE_SETEUID
733
848
                 || seteuid(uid) < 0
734
849
#endif
735
850
                ) {
736
 
                        rsyserr(FLOG, errno, "setuid %d failed", (int)uid);
 
851
                        rsyserr(FLOG, errno, "setuid %ld failed", (long)uid);
737
852
                        io_printf(f_out, "@ERROR: setuid failed\n");
738
853
                        return -1;
739
854
                }
756
871
        read_args(f_in, name, line, sizeof line, rl_nulls, &argv, &argc, &request);
757
872
        orig_argv = argv;
758
873
 
759
 
        verbose = 0; /* future verbosity is controlled by client options */
 
874
        save_munge_symlinks = munge_symlinks;
 
875
 
 
876
        reset_output_levels(); /* future verbosity is controlled by client options */
760
877
        ret = parse_arguments(&argc, (const char ***) &argv);
761
878
        if (protect_args && ret) {
762
879
                orig_early_argv = orig_argv;
767
884
        } else
768
885
                orig_early_argv = NULL;
769
886
 
 
887
        munge_symlinks = save_munge_symlinks; /* The client mustn't control this. */
 
888
 
770
889
        if (pre_exec_pid) {
771
 
                err_msg = finish_pre_exec(pre_exec_pid, pre_exec_fd, request,
772
 
                                          orig_early_argv, orig_argv);
 
890
                err_msg = finish_pre_exec(pre_exec_pid, pre_exec_arg_fd, pre_exec_error_fd,
 
891
                                          request, orig_early_argv, orig_argv);
773
892
        }
774
893
 
775
894
        if (orig_early_argv)
807
926
 
808
927
#ifndef DEBUG
809
928
        /* don't allow the logs to be flooded too fast */
810
 
        if (verbose > lp_max_verbosity(i))
811
 
                verbose = lp_max_verbosity(i);
 
929
        limit_output_verbosity(lp_max_verbosity(i));
812
930
#endif
813
931
 
814
932
        if (protocol_version < 23
815
933
            && (protocol_version == 22 || am_sender))
816
 
                io_start_multiplex_out();
 
934
                io_start_multiplex_out(f_out);
817
935
        else if (!ret || err_msg) {
818
936
                /* We have to get I/O multiplexing started so that we can
819
937
                 * get the error back to the client.  This means getting
837
955
                        if (files_from)
838
956
                                write_byte(f_out, 0);
839
957
                }
840
 
                io_start_multiplex_out();
 
958
                io_start_multiplex_out(f_out);
841
959
        }
842
960
 
843
961
        if (!ret || err_msg) {
844
 
                if (err_msg)
845
 
                        rwrite(FERROR, err_msg, strlen(err_msg), 0);
846
 
                else
 
962
                if (err_msg) {
 
963
                        while ((p = strchr(err_msg, '\n')) != NULL) {
 
964
                                int len = p - err_msg + 1;
 
965
                                rwrite(FERROR, err_msg, len, 0);
 
966
                                err_msg += len;
 
967
                        }
 
968
                        if (*err_msg)
 
969
                                rprintf(FERROR, "%s\n", err_msg);
 
970
                } else
847
971
                        option_error();
848
972
                msleep(400);
849
973
                exit_cleanup(RERR_UNSUPPORTED);
891
1015
   with "list = False". */
892
1016
static void send_listing(int fd)
893
1017
{
894
 
        int n = lp_numservices();
 
1018
        int n = lp_num_modules();
895
1019
        int i;
896
1020
 
897
1021
        for (i = 0; i < n; i++) {
920
1044
int start_daemon(int f_in, int f_out)
921
1045
{
922
1046
        char line[1024];
923
 
        char *addr, *host;
 
1047
        const char *addr, *host;
924
1048
        int i;
925
1049
 
926
1050
        io_set_sock_fds(f_in, f_out);
933
1057
                exit_cleanup(RERR_SYNTAX);
934
1058
 
935
1059
        addr = client_addr(f_in);
936
 
        host = client_name(f_in);
 
1060
        host = lp_reverse_lookup(-1) ? client_name(f_in) : undetermined_hostname;
937
1061
        rprintf(FLOG, "connect from %s (%s)\n", host, addr);
938
1062
 
939
1063
        if (!am_server) {
945
1069
                return -1;
946
1070
 
947
1071
        line[0] = 0;
948
 
        if (!read_line_old(f_in, line, sizeof line))
 
1072
        if (!read_line_old(f_in, line, sizeof line, 0))
949
1073
                return -1;
950
1074
 
951
1075
        if (!*line || strcmp(line, "#list") == 0) {
987
1111
                return;
988
1112
 
989
1113
        cleanup_set_pid(pid);
990
 
        if ((fd = do_open(pid_file, O_WRONLY|O_CREAT|O_EXCL, 0666 & ~orig_umask)) == -1) {
 
1114
        if ((fd = do_open(pid_file, O_WRONLY|O_CREAT|O_EXCL, 0666)) == -1) {
991
1115
          failure:
992
1116
                cleanup_set_pid(0);
993
1117
                fprintf(stderr, "failed to create pid file %s: %s\n", pid_file, strerror(errno));
994
1118
                rsyserr(FLOG, errno, "failed to create pid file %s", pid_file);
995
1119
                exit_cleanup(RERR_FILEIO);
996
1120
        }
997
 
        snprintf(pidbuf, sizeof pidbuf, "%ld\n", (long)pid);
 
1121
        snprintf(pidbuf, sizeof pidbuf, "%d\n", (int)pid);
998
1122
        len = strlen(pidbuf);
999
1123
        if (write(fd, pidbuf, len) != len)
1000
1124
                goto failure;
1055
1179
                fprintf(stderr, "Failed to parse config file: %s\n", config_file);
1056
1180
                exit_cleanup(RERR_SYNTAX);
1057
1181
        }
 
1182
        set_dparams(0);
1058
1183
 
1059
1184
        if (no_detach)
1060
1185
                create_pid_file();