Fix --remove-source-files sanity check w/--copy-links the right way.
[rsync.git] / authenticate.c
index 3381b8c77a747a7a47a273f6272a6db6def1ed02..8534a0b2f576c1ef853b9a3b54877493e03eb794 100644 (file)
@@ -2,7 +2,7 @@
  * Support rsync daemon authentication.
  *
  * Copyright (C) 1998-2000 Andrew Tridgell
- * Copyright (C) 2002-2014 Wayne Davison
+ * Copyright (C) 2002-2018 Wayne Davison
  *
  * 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
@@ -71,7 +71,7 @@ static void gen_challenge(const char *addr, char *challenge)
        SIVAL(input, 20, tv.tv_usec);
        SIVAL(input, 24, getpid());
 
-       sum_init(0);
+       sum_init(-1, 0);
        sum_update(input, sizeof input);
        len = sum_end(digest);
 
@@ -85,7 +85,7 @@ static void generate_hash(const char *in, const char *challenge, char *out)
        char buf[MAX_DIGEST_LEN];
        int len;
 
-       sum_init(0);
+       sum_init(-1, 0);
        sum_update(in, strlen(in));
        sum_update(challenge, strlen(challenge));
        len = sum_end(buf);
@@ -102,15 +102,16 @@ static const char *check_secret(int module, const char *user, const char *group,
        char pass2[MAX_DIGEST_LEN*2];
        const char *fname = lp_secrets_file(module);
        STRUCT_STAT st;
-       int fd, ok = 1;
+       int ok = 1;
        int user_len = strlen(user);
        int group_len = group ? strlen(group) : 0;
        char *err;
+       FILE *fh;
 
-       if (!fname || !*fname || (fd = open(fname, O_RDONLY)) < 0)
+       if (!fname || !*fname || (fh = fopen(fname, "r")) == NULL)
                return "no secrets file";
 
-       if (do_fstat(fd, &st) == -1) {
+       if (do_fstat(fileno(fh), &st) == -1) {
                rsyserr(FLOG, errno, "fstat(%s)", fname);
                ok = 0;
        } else if (lp_strict_modes(module)) {
@@ -123,29 +124,30 @@ static const char *check_secret(int module, const char *user, const char *group,
                }
        }
        if (!ok) {
-               close(fd);
+               fclose(fh);
                return "ignoring secrets file";
        }
 
        if (*user == '#') {
                /* Reject attempt to match a comment. */
-               close(fd);
+               fclose(fh);
                return "invalid username";
        }
 
        /* Try to find a line that starts with the user (or @group) name and a ':'. */
        err = "secret not found";
-       while ((user || group) && read_line_old(fd, line, sizeof line, 1)) {
-               const char **ptr, *s;
+       while ((user || group) && fgets(line, sizeof line, fh) != NULL) {
+               const char **ptr, *s = strtok(line, "\n\r");
                int len;
-               if (*line == '@') {
+               if (!s)
+                       continue;
+               if (*s == '@') {
                        ptr = &group;
                        len = group_len;
-                       s = line+1;
+                       s++;
                } else {
                        ptr = &user;
                        len = user_len;
-                       s = line;
                }
                if (!*ptr || strncmp(s, *ptr, len) != 0 || s[len] != ':')
                        continue;
@@ -158,10 +160,10 @@ static const char *check_secret(int module, const char *user, const char *group,
                *ptr = NULL; /* Don't look for name again. */
        }
 
-       close(fd);
+       fclose(fh);
 
-       memset(line, 0, sizeof line);
-       memset(pass2, 0, sizeof pass2);
+       force_memzero(line, sizeof line);
+       force_memzero(pass2, sizeof pass2);
 
        return err;
 }
@@ -277,17 +279,18 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
                        /* See if authorizing user is a real user, and if so, see
                         * if it is in a group that matches tok+1 wildmat. */
                        if (auth_uid_groups_cnt < 0) {
-                               gid_t gid_list[64];
+                               item_list gid_list = EMPTY_ITEM_LIST;
                                uid_t auth_uid;
-                               auth_uid_groups_cnt = sizeof gid_list / sizeof (gid_t);
                                if (!user_to_uid(line, &auth_uid, False)
-                                || getallgroups(auth_uid, gid_list, &auth_uid_groups_cnt) != NULL)
+                                || getallgroups(auth_uid, &gid_list) != NULL)
                                        auth_uid_groups_cnt = 0;
                                else {
+                                       gid_t *gid_array = gid_list.items;
+                                       auth_uid_groups_cnt = gid_list.count;
                                        if ((auth_uid_groups = new_array(char *, auth_uid_groups_cnt)) == NULL)
                                                out_of_memory("auth_server");
                                        for (j = 0; j < auth_uid_groups_cnt; j++)
-                                               auth_uid_groups[j] = gid_to_group(gid_list[j]);
+                                               auth_uid_groups[j] = gid_to_group(gid_array[j]);
                                }
                        }
                        for (j = 0; j < auth_uid_groups_cnt; j++) {
@@ -315,8 +318,8 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
                err = check_secret(module, line, group, challenge, pass);
        }
 
-       memset(challenge, 0, sizeof challenge);
-       memset(pass, 0, strlen(pass));
+       force_memzero(challenge, sizeof challenge);
+       force_memzero(pass, strlen(pass));
 
        if (auth_uid_groups) {
                int j;