char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int bit_offset, byte_offset, idx, i;
unsigned char *d = (unsigned char *)buf;
- char *p;
int bytes = (len*8 + 5)/6;
memset(out, 0, bytes+1);
memset(input, 0, sizeof(input));
- strncpy((char *)input, addr, 16);
+ strlcpy((char *)input, addr, 16);
gettimeofday(&tv, NULL);
SIVAL(input, 16, tv.tv_sec);
SIVAL(input, 20, tv.tv_usec);
{
char *fname = lp_secrets_file(module);
int fd, found=0;
- char line[1024];
- char *p, *pass;
+ char line[MAXPATHLEN];
+ char *p, *pass=NULL;
if (!fname || !*fname) return 0;
char *users = lp_auth_users(module);
char challenge[16];
char b64_challenge[30];
- char line[1024];
+ char line[MAXPATHLEN];
char user[100];
char secret[100];
char pass[30];
int fd, i;
char *sargs[MAX_ARGS];
int sargc=0;
- char line[1024];
+ char line[MAXPATHLEN];
char *p, *user=NULL;
extern int remote_version;
int argc=0;
char *argv[MAX_ARGS];
char **argp;
- char line[1024];
+ char line[MAXPATHLEN];
uid_t uid;
gid_t gid;
char *p;
char *addr = client_addr(fd);
char *host = client_name(fd);
- char *auth;
char *name = lp_name(i);
int start_glob=0;
p = line;
- if (start_glob && strncmp(p, name, strlen(name)) == 0) {
- p += strlen(name);
- if (!*p) p = ".";
- }
-
argv[argc] = strdup(p);
if (!argv[argc]) {
return -1;
}
if (start_glob) {
+ rprintf(FINFO,"transferring %s\n",p);
glob_expand(name, argv, &argc, MAX_ARGS);
} else {
argc++;
become_daemon();
+ rprintf(FINFO,"rsyncd version %s starting\n",VERSION);
+
start_accept_loop(rsync_port, start_daemon);
return -1;
}
add_exclude(cvs_ignore_list[i]);
if ((p=getenv("HOME")) && strlen(p) < (MAXPATHLEN-12)) {
- sprintf(fname,"%s/.cvsignore",p);
- add_exclude_file(fname,0);
+ slprintf(fname,sizeof(fname)-1, "%s/.cvsignore",p);
+ add_exclude_file(fname,0);
}
add_exclude_line(getenv("CVSIGNORE"));
closedir(d);
return;
}
- strcat(fname,"/");
+ strlcat(fname,"/", MAXPATHLEN-1);
l++;
}
p = fname + strlen(fname);
l = strlen(fname);
if (l != 1 && fname[l-1] == '/') {
- strcat(fname,".");
+ strlcat(fname,".",MAXPATHLEN-1);
}
if (link_stat(fname,&st) != 0) {
n = (n+1)%10;
if (f->dirname) {
- sprintf(p, "%s/%s", f->dirname, f->basename);
+ slprintf(p, MAXPATHLEN-1, "%s/%s", f->dirname, f->basename);
} else {
strlcpy(p, f->basename, MAXPATHLEN-1);
}
int len;
va_start(ap, format);
-
-#if HAVE_VSNPRINTF
- len = vsnprintf(buf, sizeof(buf)-1, format, ap);
-#else
- vsprintf(buf, format, ap);
- len = strlen(buf);
-#endif
+ len = vslprintf(buf, sizeof(buf)-1, format, ap);
va_end(ap);
if (len < 0) exit_cleanup(1);
*/
#include "rsync.h"
+
/* this is the rsync debugging function. Call it with FINFO or FERROR */
void rprintf(int fd, const char *format, ...)
{
extern int am_daemon;
va_start(ap, format);
-
-#if HAVE_VSNPRINTF
- len = vsnprintf(buf, sizeof(buf)-1, format, ap);
-#else
- vsprintf(buf, format, ap);
- len = strlen(buf);
-#endif
+ len = vslprintf(buf, sizeof(buf)-1, format, ap);
va_end(ap);
if (len < 0) exit_cleanup(1);
struct file_list *flist;
char *dir = argv[0];
extern int relative_paths;
- extern int am_daemon;
extern int recurse;
if (verbose > 2)
if (strcmp(dname,".")==0 ||
strcmp(dname,"..")==0)
continue;
- strlcpy(buf, fname, (MAXPATHLEN-strlen(dname))-2);
- strcat(buf, "/");
- strcat(buf, dname);
- buf[MAXPATHLEN-1] = 0;
+ slprintf(buf, sizeof(buf)-1, "%s/%s", fname, dname);
if (verbose > 0)
rprintf(FINFO,"deleting %s\n", buf);
if (delete_file(buf) != 0) {
close(fd1);
continue;
}
- sprintf(fnametmp,"%s/.%s.XXXXXX",tmpdir,f);
+ slprintf(fnametmp,sizeof(fnametmp)-1, "%s/.%s.XXXXXX",tmpdir,f);
} else {
char *f = strrchr(fname,'/');
if (f) {
*f = 0;
- sprintf(fnametmp,"%s/.%s.XXXXXX",fname,f+1);
+ slprintf(fnametmp,sizeof(fnametmp)-1,"%s/.%s.XXXXXX",fname,f+1);
*f = '/';
} else {
- sprintf(fnametmp,".%s.XXXXXX",fname);
+ slprintf(fnametmp,sizeof(fnametmp)-1,".%s.XXXXXX",fname);
}
}
if (NULL == do_mktemp(fnametmp)) {
rprintf(FERROR,"backup filename too long\n");
continue;
}
- sprintf(fnamebak,"%s%s",fname,backup_suffix);
+ slprintf(fnamebak,sizeof(fnamebak)-1,"%s%s",fname,backup_suffix);
if (do_rename(fname,fnamebak) != 0 && errno != ENOENT) {
rprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
continue;
fname);
return;
}
- strcat(fname,"/");
+ strlcat(fname,"/",MAXPATHLEN-1);
offset = strlen(file->basedir)+1;
}
- strncat(fname,f_name(file),MAXPATHLEN-strlen(fname));
+ strlcat(fname,f_name(file),MAXPATHLEN-strlen(fname));
if (verbose > 2)
rprintf(FINFO,"send_files(%d,%s)\n",i,fname);
d[len] = 0;
}
+/* like strncat but does not 0 fill the buffer and always null
+ terminates (thus it can use maxlen+1 space in d) */
+void strlcat(char *d, char *s, int maxlen)
+{
+ int len1 = strlen(d);
+ int len2 = strlen(s);
+ if (len1+len2 > maxlen) {
+ len2 = maxlen-len1;
+ }
+ if (len2 > 0) {
+ memcpy(d+len1, s, len2);
+ d[len1+len2] = 0;
+ }
+}
+
/* turn a user name into a uid */
int name_to_uid(char *name, uid_t *uid)
{
static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
{
#ifndef HAVE_GLOB
+ if (!*s) s = ".";
argv[*argc] = strdup(s);
(*argc)++;
return;
glob_t globbuf;
int i;
+ if (!*s) s = ".";
+
argv[*argc] = strdup(s);
memset(&globbuf, 0, sizeof(globbuf));
if (!s || !*s) return;
+ if (strncmp(s, base, strlen(base)) == 0) {
+ s += strlen(base);
+ }
+
s = strdup(s);
if (!s) out_of_memory("glob_expand");
/* split it at this point */
*(p-1) = 0;
glob_expand_one(q, argv, argc, maxargs);
- q = p+strlen(base);
+ q = p+strlen(base)+1;
} else {
q++;
}
s++;
}
}
+
+/* this is like vsnprintf but the 'n' limit does not include
+ the terminating null. So if you have a 1024 byte buffer then
+ pass 1023 for n */
+int vslprintf(char *str, int n, const char *format, va_list ap)
+{
+#ifdef HAVE_VSNPRINTF
+ int ret = vsnprintf(str, n, format, ap);
+ if (ret > n || ret < 0) {
+ str[n] = 0;
+ return -1;
+ }
+ str[ret] = 0;
+ return ret;
+#else
+ static char *buf;
+ static int len=MAXPATHLEN*8;
+ int ret;
+
+ /* this code is NOT a proper vsnprintf() implementation. It
+ relies on the fact that all calls to slprintf() in rsync
+ pass strings which have already been checked to be less
+ than MAXPATHLEN in length and never more than 2 strings are
+ concatenated. This means the above buffer is absolutely
+ ample and can never be overflowed.
+
+ In the future we would like to replace this with a proper
+ vsnprintf() implementation but right now we need a solution
+ that is secure and portable. This is it. */
+
+ if (!buf) {
+ buf = malloc(len);
+ if (!buf) {
+ /* can't call debug or we would recurse */
+ exit(1);
+ }
+ }
+
+ ret = vsprintf(buf, format, ap);
+
+ if (ret < 0) {
+ str[0] = 0;
+ return -1;
+ }
+
+ if (ret < n) {
+ n = ret;
+ } else if (ret > n) {
+ ret = -1;
+ }
+
+ buf[n] = 0;
+
+ memcpy(str, buf, n+1);
+
+ return ret;
+#endif
+}
+
+
+/* like snprintf but always null terminates */
+int slprintf(char *str, int n, char *format, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, format);
+ ret = vslprintf(str,n,format,ap);
+ va_end(ap);
+ return ret;
+}