Print this page
10151 mv_xattrs() checks for a NULL array name
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libcmdutils/common/process_xattrs.c
+++ new/usr/src/lib/libcmdutils/common/process_xattrs.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 * Copyright 2012 Milan Jurik. All rights reserved.
26 + * Copyright (c) 2018, Joyent, Inc.
26 27 */
27 28
28 29 #include "libcmdutils.h"
29 30
30 31
31 32 /*
32 33 * Gets file descriptors of attribute directories for source and target
33 34 * attribute files
34 35 */
35 36 int
36 37 get_attrdirs(int indfd, int outdfd, char *attrfile, int *sfd, int *tfd)
37 38 {
38 39 int pwdfd;
39 40 int fd1;
40 41 int fd2;
41 42
42 43 pwdfd = open(".", O_RDONLY);
43 44 if ((pwdfd != -1) && (fchdir(indfd) == 0)) {
44 45 if ((fd1 = attropen(attrfile, ".", O_RDONLY)) == -1) {
45 46 (void) fchdir(pwdfd);
46 47 (void) close(pwdfd);
47 48 return (1);
48 49 }
49 50 *sfd = fd1;
50 51 } else {
51 52 (void) fchdir(pwdfd);
52 53 (void) close(pwdfd);
53 54 return (1);
54 55 }
55 56 if (fchdir(outdfd) == 0) {
56 57 if ((fd2 = attropen(attrfile, ".", O_RDONLY)) == -1) {
57 58 (void) fchdir(pwdfd);
58 59 (void) close(pwdfd);
59 60 return (1);
60 61 }
61 62 *tfd = fd2;
62 63 } else {
63 64 (void) fchdir(pwdfd);
64 65 (void) close(pwdfd);
65 66 return (1);
66 67 }
67 68 (void) fchdir(pwdfd);
68 69 return (0);
69 70 }
70 71
71 72 /*
72 73 * mv_xattrs - Copies the content of the extended attribute files. Then
73 74 * moves the extended system attributes from the input attribute files
74 75 * to the target attribute files. Moves the extended system attributes
75 76 * from source to the target file. This function returns 0 on success
76 77 * and nonzero on error.
77 78 */
78 79 int
79 80 mv_xattrs(char *cmd, char *infile, char *outfile, int sattr, int silent)
80 81 {
81 82 int srcfd = -1;
82 83 int indfd = -1;
83 84 int outdfd = -1;
84 85 int tmpfd = -1;
85 86 int sattrfd = -1;
86 87 int tattrfd = -1;
87 88 int asfd = -1;
88 89 int atfd = -1;
89 90 DIR *dirp = NULL;
90 91 struct dirent *dp = NULL;
91 92 char *etext = NULL;
92 93 struct stat st1;
93 94 struct stat st2;
94 95 nvlist_t *response = NULL;
95 96 nvlist_t *res = NULL;
96 97
97 98 if ((srcfd = open(infile, O_RDONLY)) == -1) {
98 99 etext = dgettext(TEXT_DOMAIN, "cannot open source");
99 100 goto error;
100 101 }
101 102 if (sattr)
102 103 response = sysattr_list(cmd, srcfd, infile);
103 104
104 105 if ((indfd = openat(srcfd, ".", O_RDONLY|O_XATTR)) == -1) {
105 106 etext = dgettext(TEXT_DOMAIN, "cannot openat source");
106 107 goto error;
107 108 }
108 109 if ((outdfd = attropen(outfile, ".", O_RDONLY)) == -1) {
109 110 etext = dgettext(TEXT_DOMAIN, "cannot attropen target");
110 111 goto error;
111 112 }
112 113 if ((tmpfd = dup(indfd)) == -1) {
113 114 etext = dgettext(TEXT_DOMAIN, "cannot dup descriptor");
114 115 goto error;
115 116
116 117 }
117 118 if ((dirp = fdopendir(tmpfd)) == NULL) {
118 119 etext = dgettext(TEXT_DOMAIN, "cannot access source");
119 120 goto error;
120 121 }
121 122 while ((dp = readdir(dirp)) != NULL) {
122 123 if ((dp->d_name[0] == '.' && dp->d_name[1] == '\0') ||
123 124 (dp->d_name[0] == '.' && dp->d_name[1] == '.' &&
124 125 dp->d_name[2] == '\0') ||
125 126 (sysattr_type(dp->d_name) == _RO_SATTR) ||
126 127 (sysattr_type(dp->d_name) == _RW_SATTR))
127 128 continue;
128 129
129 130 if ((sattrfd = openat(indfd, dp->d_name,
130 131 O_RDONLY)) == -1) {
131 132 etext = dgettext(TEXT_DOMAIN,
132 133 "cannot open src attribute file");
133 134 goto error;
134 135 }
135 136 if (fstat(sattrfd, &st1) < 0) {
136 137 etext = dgettext(TEXT_DOMAIN,
137 138 "could not stat attribute file");
138 139 goto error;
139 140 }
140 141 if ((tattrfd = openat(outdfd, dp->d_name,
141 142 O_RDWR|O_CREAT|O_TRUNC, st1.st_mode)) == -1) {
142 143 etext = dgettext(TEXT_DOMAIN,
143 144 "cannot open target attribute file");
144 145 goto error;
145 146 }
146 147 if (fstat(tattrfd, &st2) < 0) {
147 148 etext = dgettext(TEXT_DOMAIN,
148 149 "could not stat attribute file");
149 150 goto error;
150 151 }
151 152 if (writefile(sattrfd, tattrfd, infile, outfile, dp->d_name,
152 153 dp->d_name, &st1, &st2) != 0) {
153 154 etext = dgettext(TEXT_DOMAIN,
154 155 "failed to copy extended attribute "
↓ open down ↓ |
119 lines elided |
↑ open up ↑ |
155 156 "from source to target");
156 157 goto error;
157 158 }
158 159
159 160 errno = 0;
160 161 if (sattr) {
161 162 /*
162 163 * Gets non default extended system attributes from
163 164 * source to copy to target.
164 165 */
165 - if (dp->d_name != NULL)
166 - res = sysattr_list(cmd, sattrfd, dp->d_name);
166 + res = sysattr_list(cmd, sattrfd, dp->d_name);
167 167
168 168 if (res != NULL &&
169 169 get_attrdirs(indfd, outdfd, dp->d_name, &asfd,
170 170 &atfd) != 0) {
171 171 etext = dgettext(TEXT_DOMAIN,
172 172 "Failed to open attribute files");
173 173 goto error;
174 174 }
175 175 /*
176 176 * Copy extended system attribute from source
177 177 * attribute file to target attribute file
178 178 */
179 179 if (res != NULL &&
180 180 (renameat(asfd, VIEW_READWRITE, atfd,
181 181 VIEW_READWRITE) != 0)) {
182 182 if (errno == EPERM)
183 183 etext = dgettext(TEXT_DOMAIN,
184 184 "Permission denied -"
185 185 "failed to move system attribute");
186 186 else
187 187 etext = dgettext(TEXT_DOMAIN,
188 188 "failed to move extended "
189 189 "system attribute");
190 190 goto error;
191 191 }
192 192 }
193 193 if (sattrfd != -1)
194 194 (void) close(sattrfd);
195 195 if (tattrfd != -1)
196 196 (void) close(tattrfd);
197 197 if (asfd != -1)
198 198 (void) close(asfd);
199 199 if (atfd != -1)
200 200 (void) close(atfd);
201 201 if (res != NULL) {
202 202 nvlist_free(res);
203 203 res = NULL;
204 204 }
205 205 }
206 206 errno = 0;
207 207 /* Copy extended system attribute from source to target */
208 208
209 209 if (response != NULL) {
210 210 if (renameat(indfd, VIEW_READWRITE, outdfd,
211 211 VIEW_READWRITE) == 0)
212 212 goto done;
213 213
214 214 if (errno == EPERM)
215 215 etext = dgettext(TEXT_DOMAIN, "Permission denied");
216 216 else
217 217 etext = dgettext(TEXT_DOMAIN,
218 218 "failed to move system attribute");
219 219 }
220 220 error:
221 221 nvlist_free(res);
222 222 if (silent == 0 && etext != NULL) {
223 223 if (!sattr)
224 224 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
225 225 "%s: %s: cannot move extended attributes, "),
226 226 cmd, infile);
227 227 else
228 228 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
229 229 "%s: %s: cannot move extended system "
230 230 "attributes, "), cmd, infile);
231 231 perror(etext);
232 232 }
233 233 done:
234 234 if (dirp)
235 235 (void) closedir(dirp);
236 236 if (sattrfd != -1)
237 237 (void) close(sattrfd);
238 238 if (tattrfd != -1)
239 239 (void) close(tattrfd);
240 240 if (asfd != -1)
241 241 (void) close(asfd);
242 242 if (atfd != -1)
243 243 (void) close(atfd);
244 244 if (indfd != -1)
245 245 (void) close(indfd);
246 246 if (outdfd != -1)
247 247 (void) close(outdfd);
248 248 nvlist_free(response);
249 249 if (etext != NULL)
250 250 return (1);
251 251 else
252 252 return (0);
253 253 }
254 254
255 255 /*
256 256 * The function returns non default extended system attribute list
257 257 * associated with 'fname' and returns NULL when an error has occured
258 258 * or when only extended system attributes other than archive,
259 259 * av_modified or crtime are set.
260 260 *
261 261 * The function returns system attribute list for the following cases:
262 262 *
263 263 * - any extended system attribute other than the default attributes
264 264 * ('archive', 'av_modified' and 'crtime') is set
265 265 * - nvlist has NULL name string
266 266 * - nvpair has data type of 'nvlist'
267 267 * - default data type.
268 268 */
269 269
270 270 nvlist_t *
271 271 sysattr_list(char *cmd, int fd, char *fname)
272 272 {
273 273 boolean_t value;
274 274 data_type_t type;
275 275 nvlist_t *response;
276 276 nvpair_t *pair;
277 277 f_attr_t fattr;
278 278 char *name;
279 279
280 280 if (fgetattr(fd, XATTR_VIEW_READWRITE, &response) != 0) {
281 281 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
282 282 "%s: %s: fgetattr failed\n"),
283 283 cmd, fname);
284 284 return (NULL);
285 285 }
286 286 pair = NULL;
287 287 while ((pair = nvlist_next_nvpair(response, pair)) != NULL) {
288 288
289 289 name = nvpair_name(pair);
290 290
291 291 if (name != NULL)
292 292 fattr = name_to_attr(name);
293 293 else
294 294 return (response);
295 295
296 296 type = nvpair_type(pair);
297 297 switch (type) {
298 298 case DATA_TYPE_BOOLEAN_VALUE:
299 299 if (nvpair_value_boolean_value(pair,
300 300 &value) != 0) {
301 301 (void) fprintf(stderr,
302 302 dgettext(TEXT_DOMAIN, "%s "
303 303 "nvpair_value_boolean_value "
304 304 "failed\n"), cmd);
305 305 continue;
306 306 }
307 307 if (value && fattr != F_ARCHIVE &&
308 308 fattr != F_AV_MODIFIED)
309 309 return (response);
310 310 break;
311 311 case DATA_TYPE_UINT64_ARRAY:
312 312 if (fattr != F_CRTIME)
313 313 return (response);
314 314 break;
315 315 case DATA_TYPE_NVLIST:
316 316 default:
317 317 return (response);
318 318 }
319 319 }
320 320 nvlist_free(response);
321 321 return (NULL);
322 322 }
↓ open down ↓ |
146 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX