1 #include "../burp.h"
2 #include "../alloc.h"
3 #include "../bfile.h"
4 #include "../cmd.h"
5 #include "../conf.h"
6 #include "../log.h"
7 #include "acl.h"
8 #include "cvss.h"
9 #include "extrameta.h"
10 #include "xattr.h"
11 
has_extrameta(const char * path,enum cmd cmd,int enable_acl,int enable_xattr)12 int has_extrameta(const char *path, enum cmd cmd,
13 	int enable_acl, int enable_xattr)
14 {
15 #if defined(WIN32_VSS)
16 	return 1;
17 #endif
18 #if defined(HAVE_LINUX_OS) || \
19     defined(HAVE_FREEBSD_OS) || \
20     defined(HAVE_NETBSD_OS)
21 
22 #ifdef HAVE_ACL
23 	if(enable_acl && has_acl(path, cmd))
24 		return 1;
25 #endif
26 #endif
27 #if defined(HAVE_LINUX_OS) || \
28     defined(HAVE_FREEBSD_OS) || \
29     defined(HAVE_NETBSD_OS) || \
30     defined(HAVE_DARWIN_OS)
31 #ifdef HAVE_XATTR
32 	if(enable_xattr && has_xattr(path))
33 		return 1;
34 #endif
35 #endif
36         return 0;
37 }
38 
get_extrameta(struct asfd * asfd,struct BFILE * bfd,const char * path,int isdir,char ** extrameta,size_t * elen,struct cntr * cntr)39 int get_extrameta(struct asfd *asfd,
40 #ifdef HAVE_WIN32
41 	struct BFILE *bfd,
42 #endif
43 	const char *path,
44 	int isdir,
45 	char **extrameta,
46 	size_t *elen,
47 	struct cntr *cntr)
48 {
49 #if defined (WIN32_VSS)
50 	if(get_vss(bfd, extrameta, elen))
51 		return -1;
52 #endif
53 	// Important to do xattr directly after acl, because xattr is excluding
54 	// some entries if acls were set.
55 #if defined(HAVE_LINUX_OS) || \
56     defined(HAVE_FREEBSD_OS) || \
57     defined(HAVE_NETBSD_OS)
58 #ifdef HAVE_ACL
59 	if(get_acl(asfd, path, isdir, extrameta, elen, cntr))
60 		return -1;
61 #endif
62 #endif
63 #if defined(HAVE_LINUX_OS) || \
64     defined(HAVE_FREEBSD_OS) || \
65     defined(HAVE_NETBSD_OS) || \
66     defined(HAVE_DARWIN_OS)
67 #ifdef HAVE_XATTR
68 	if(get_xattr(asfd, path, extrameta, elen, cntr))
69 		return -1;
70 #endif
71 #endif
72         return 0;
73 }
74 
set_extrameta(struct asfd * asfd,struct BFILE * bfd,const char * path,const char * extrameta,size_t metalen,struct cntr * cntr)75 int set_extrameta(struct asfd *asfd,
76 #ifdef HAVE_WIN32
77 	struct BFILE *bfd,
78 #endif
79 	const char *path,
80 	const char *extrameta,
81 	size_t metalen,
82 	struct cntr *cntr)
83 {
84 	size_t l=0;
85 	char cmdtmp='\0';
86 	uint32_t s=0;
87 	const char *metadata=NULL;
88 	int errors=0;
89 
90 	metadata=extrameta;
91 	l=metalen;
92 	while(l>0)
93 	{
94 		char *m=NULL;
95 		if(l<9)
96 		{
97 			logw(asfd, cntr,
98 				"length of metadata '%s' %d is too short for %s\n",
99 				metadata, (uint32_t)l, path);
100 			return -1;
101 		}
102 		if((sscanf(metadata, "%c%08X", &cmdtmp, &s))!=2)
103 		{
104 			logw(asfd, cntr,
105 				"sscanf of metadata '%s' %d failed for %s\n",
106 				metadata, (uint32_t)l, path);
107 			return -1;
108 		}
109 		metadata+=9;
110 		l-=9;
111 		if(s>l)
112 		{
113 			logw(asfd, cntr, "requested length %d of metadata '%s' %d is too long for %s\n",
114 				s, metadata, (uint32_t)l, path);
115 			return -1;
116 
117 		}
118 		if(!(m=(char *)malloc_w(s+1, __func__)))
119 			return -1;
120 		memcpy(m, metadata, s);
121 		m[s]='\0';
122 
123 		metadata+=s;
124 		l-=s;
125 
126 		switch(cmdtmp)
127 		{
128 #if defined(HAVE_WIN32)
129 			case META_VSS:
130 				if(set_vss(bfd, m, s))
131 					errors++;
132 				break;
133 #endif
134 #if defined(HAVE_LINUX_OS) || \
135     defined(HAVE_FREEBSD_OS) || \
136     defined(HAVE_NETBSD_OS)
137 #ifdef HAVE_ACL
138 			case META_ACCESS_ACL:
139 				if(set_acl(asfd, path, m, cmdtmp, cntr))
140 					errors++;
141 				break;
142 			case META_DEFAULT_ACL:
143 				if(set_acl(asfd, path, m, cmdtmp, cntr))
144 					errors++;
145 				break;
146 #endif
147 #endif
148 #if defined(HAVE_LINUX_OS) || \
149     defined(HAVE_DARWIN_OS)
150 #ifdef HAVE_XATTR
151 			case META_XATTR:
152 				if(set_xattr(asfd,
153 					path, m, s, cmdtmp, cntr))
154 						errors++;
155 				break;
156 #endif
157 #endif
158 #if defined(HAVE_FREEBSD_OS) || \
159     defined(HAVE_NETBSD_OS)
160 #ifdef HAVE_XATTR
161 			case META_XATTR_BSD:
162 				if(set_xattr(asfd,
163 					path, m, s, cmdtmp, cntr))
164 						errors++;
165 				break;
166 #endif
167 #endif
168 			default:
169 				logp("unknown metadata: %c\n", cmdtmp);
170 				logw(asfd, cntr,
171 					"unknown metadata: %c\n", cmdtmp);
172 				errors++;
173 				break;
174 
175 		}
176 		free_w(&m);
177 	}
178 
179 	return errors;
180 }
181