1987da915Sopenharmony_ci/** 2987da915Sopenharmony_ci * xattrs.c : common functions to deal with system extended attributes 3987da915Sopenharmony_ci * 4987da915Sopenharmony_ci * Copyright (c) 2010-2014 Jean-Pierre Andre 5987da915Sopenharmony_ci * 6987da915Sopenharmony_ci * This program/include file is free software; you can redistribute it and/or 7987da915Sopenharmony_ci * modify it under the terms of the GNU General Public License as published 8987da915Sopenharmony_ci * by the Free Software Foundation; either version 2 of the License, or 9987da915Sopenharmony_ci * (at your option) any later version. 10987da915Sopenharmony_ci * 11987da915Sopenharmony_ci * This program/include file is distributed in the hope that it will be 12987da915Sopenharmony_ci * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 13987da915Sopenharmony_ci * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14987da915Sopenharmony_ci * GNU General Public License for more details. 15987da915Sopenharmony_ci * 16987da915Sopenharmony_ci * You should have received a copy of the GNU General Public License 17987da915Sopenharmony_ci * along with this program (in the main directory of the NTFS-3G 18987da915Sopenharmony_ci * distribution in the file COPYING); if not, write to the Free Software 19987da915Sopenharmony_ci * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20987da915Sopenharmony_ci */ 21987da915Sopenharmony_ci 22987da915Sopenharmony_ci#ifdef HAVE_CONFIG_H 23987da915Sopenharmony_ci#include "config.h" 24987da915Sopenharmony_ci#endif 25987da915Sopenharmony_ci 26987da915Sopenharmony_ci#ifdef HAVE_STDIO_H 27987da915Sopenharmony_ci#include <stdio.h> 28987da915Sopenharmony_ci#endif 29987da915Sopenharmony_ci#ifdef HAVE_STDLIB_H 30987da915Sopenharmony_ci#include <stdlib.h> 31987da915Sopenharmony_ci#endif 32987da915Sopenharmony_ci#ifdef HAVE_STRING_H 33987da915Sopenharmony_ci#include <string.h> 34987da915Sopenharmony_ci#endif 35987da915Sopenharmony_ci#ifdef HAVE_FCNTL_H 36987da915Sopenharmony_ci#include <fcntl.h> 37987da915Sopenharmony_ci#endif 38987da915Sopenharmony_ci#ifdef HAVE_UNISTD_H 39987da915Sopenharmony_ci#include <unistd.h> 40987da915Sopenharmony_ci#endif 41987da915Sopenharmony_ci#ifdef HAVE_ERRNO_H 42987da915Sopenharmony_ci#include <errno.h> 43987da915Sopenharmony_ci#endif 44987da915Sopenharmony_ci 45987da915Sopenharmony_ci#include "types.h" 46987da915Sopenharmony_ci#include "param.h" 47987da915Sopenharmony_ci#include "layout.h" 48987da915Sopenharmony_ci#include "attrib.h" 49987da915Sopenharmony_ci#include "index.h" 50987da915Sopenharmony_ci#include "dir.h" 51987da915Sopenharmony_ci#include "security.h" 52987da915Sopenharmony_ci#include "acls.h" 53987da915Sopenharmony_ci#include "efs.h" 54987da915Sopenharmony_ci#include "reparse.h" 55987da915Sopenharmony_ci#include "object_id.h" 56987da915Sopenharmony_ci#include "ea.h" 57987da915Sopenharmony_ci#include "misc.h" 58987da915Sopenharmony_ci#include "logging.h" 59987da915Sopenharmony_ci#include "xattrs.h" 60987da915Sopenharmony_ci 61987da915Sopenharmony_ci#if POSIXACLS 62987da915Sopenharmony_ci#if __BYTE_ORDER == __BIG_ENDIAN 63987da915Sopenharmony_ci 64987da915Sopenharmony_ci/* 65987da915Sopenharmony_ci * Posix ACL structures 66987da915Sopenharmony_ci */ 67987da915Sopenharmony_ci 68987da915Sopenharmony_cistruct LE_POSIX_ACE { 69987da915Sopenharmony_ci le16 tag; 70987da915Sopenharmony_ci le16 perms; 71987da915Sopenharmony_ci le32 id; 72987da915Sopenharmony_ci} __attribute__((__packed__)); 73987da915Sopenharmony_ci 74987da915Sopenharmony_cistruct LE_POSIX_ACL { 75987da915Sopenharmony_ci u8 version; 76987da915Sopenharmony_ci u8 flags; 77987da915Sopenharmony_ci le16 filler; 78987da915Sopenharmony_ci struct LE_POSIX_ACE ace[0]; 79987da915Sopenharmony_ci} __attribute__((__packed__)); 80987da915Sopenharmony_ci 81987da915Sopenharmony_ci#endif 82987da915Sopenharmony_ci#endif 83987da915Sopenharmony_ci 84987da915Sopenharmony_cistatic const char nf_ns_xattr_ntfs_acl[] = "system.ntfs_acl"; 85987da915Sopenharmony_cistatic const char nf_ns_xattr_attrib[] = "system.ntfs_attrib"; 86987da915Sopenharmony_cistatic const char nf_ns_xattr_attrib_be[] = "system.ntfs_attrib_be"; 87987da915Sopenharmony_cistatic const char nf_ns_xattr_efsinfo[] = "system.ntfs_efsinfo"; 88987da915Sopenharmony_cistatic const char nf_ns_xattr_reparse[] = "system.ntfs_reparse_data"; 89987da915Sopenharmony_cistatic const char nf_ns_xattr_object_id[] = "system.ntfs_object_id"; 90987da915Sopenharmony_cistatic const char nf_ns_xattr_dos_name[] = "system.ntfs_dos_name"; 91987da915Sopenharmony_cistatic const char nf_ns_xattr_times[] = "system.ntfs_times"; 92987da915Sopenharmony_cistatic const char nf_ns_xattr_times_be[] = "system.ntfs_times_be"; 93987da915Sopenharmony_cistatic const char nf_ns_xattr_crtime[] = "system.ntfs_crtime"; 94987da915Sopenharmony_cistatic const char nf_ns_xattr_crtime_be[] = "system.ntfs_crtime_be"; 95987da915Sopenharmony_cistatic const char nf_ns_xattr_ea[] = "system.ntfs_ea"; 96987da915Sopenharmony_cistatic const char nf_ns_xattr_posix_access[] = "system.posix_acl_access"; 97987da915Sopenharmony_cistatic const char nf_ns_xattr_posix_default[] = "system.posix_acl_default"; 98987da915Sopenharmony_ci 99987da915Sopenharmony_cistatic const char nf_ns_alt_xattr_efsinfo[] = "user.ntfs.efsinfo"; 100987da915Sopenharmony_ci 101987da915Sopenharmony_cistruct XATTRNAME { 102987da915Sopenharmony_ci enum SYSTEMXATTRS xattr; 103987da915Sopenharmony_ci const char *name; 104987da915Sopenharmony_ci} ; 105987da915Sopenharmony_ci 106987da915Sopenharmony_cistatic struct XATTRNAME nf_ns_xattr_names[] = { 107987da915Sopenharmony_ci { XATTR_NTFS_ACL, nf_ns_xattr_ntfs_acl }, 108987da915Sopenharmony_ci { XATTR_NTFS_ATTRIB, nf_ns_xattr_attrib }, 109987da915Sopenharmony_ci { XATTR_NTFS_ATTRIB_BE, nf_ns_xattr_attrib_be }, 110987da915Sopenharmony_ci { XATTR_NTFS_EFSINFO, nf_ns_xattr_efsinfo }, 111987da915Sopenharmony_ci { XATTR_NTFS_REPARSE_DATA, nf_ns_xattr_reparse }, 112987da915Sopenharmony_ci { XATTR_NTFS_OBJECT_ID, nf_ns_xattr_object_id }, 113987da915Sopenharmony_ci { XATTR_NTFS_DOS_NAME, nf_ns_xattr_dos_name }, 114987da915Sopenharmony_ci { XATTR_NTFS_TIMES, nf_ns_xattr_times }, 115987da915Sopenharmony_ci { XATTR_NTFS_TIMES_BE, nf_ns_xattr_times_be }, 116987da915Sopenharmony_ci { XATTR_NTFS_CRTIME, nf_ns_xattr_crtime }, 117987da915Sopenharmony_ci { XATTR_NTFS_CRTIME_BE, nf_ns_xattr_crtime_be }, 118987da915Sopenharmony_ci { XATTR_NTFS_EA, nf_ns_xattr_ea }, 119987da915Sopenharmony_ci { XATTR_POSIX_ACC, nf_ns_xattr_posix_access }, 120987da915Sopenharmony_ci { XATTR_POSIX_DEF, nf_ns_xattr_posix_default }, 121987da915Sopenharmony_ci { XATTR_UNMAPPED, (char*)NULL } /* terminator */ 122987da915Sopenharmony_ci}; 123987da915Sopenharmony_ci 124987da915Sopenharmony_ci/* 125987da915Sopenharmony_ci * Make an integer big-endian 126987da915Sopenharmony_ci * 127987da915Sopenharmony_ci * Swap bytes on a small-endian computer and does nothing on a 128987da915Sopenharmony_ci * big-endian computer. 129987da915Sopenharmony_ci */ 130987da915Sopenharmony_ci 131987da915Sopenharmony_cistatic void fix_big_endian(char *p, int size) 132987da915Sopenharmony_ci{ 133987da915Sopenharmony_ci#if __BYTE_ORDER == __LITTLE_ENDIAN 134987da915Sopenharmony_ci int i,j; 135987da915Sopenharmony_ci int c; 136987da915Sopenharmony_ci 137987da915Sopenharmony_ci i = 0; 138987da915Sopenharmony_ci j = size - 1; 139987da915Sopenharmony_ci while (i < j) { 140987da915Sopenharmony_ci c = p[i]; 141987da915Sopenharmony_ci p[i++] = p[j]; 142987da915Sopenharmony_ci p[j--] = c; 143987da915Sopenharmony_ci } 144987da915Sopenharmony_ci#endif 145987da915Sopenharmony_ci} 146987da915Sopenharmony_ci 147987da915Sopenharmony_ci#if POSIXACLS 148987da915Sopenharmony_ci#if __BYTE_ORDER == __BIG_ENDIAN 149987da915Sopenharmony_ci 150987da915Sopenharmony_ci/* 151987da915Sopenharmony_ci * Make a Posix ACL CPU endian 152987da915Sopenharmony_ci */ 153987da915Sopenharmony_ci 154987da915Sopenharmony_cistatic int le_acl_to_cpu(const struct LE_POSIX_ACL *le_acl, size_t size, 155987da915Sopenharmony_ci struct POSIX_ACL *acl) 156987da915Sopenharmony_ci{ 157987da915Sopenharmony_ci int i; 158987da915Sopenharmony_ci int cnt; 159987da915Sopenharmony_ci 160987da915Sopenharmony_ci acl->version = le_acl->version; 161987da915Sopenharmony_ci acl->flags = le_acl->flags; 162987da915Sopenharmony_ci acl->filler = 0; 163987da915Sopenharmony_ci cnt = (size - sizeof(struct LE_POSIX_ACL)) / sizeof(struct LE_POSIX_ACE); 164987da915Sopenharmony_ci for (i=0; i<cnt; i++) { 165987da915Sopenharmony_ci acl->ace[i].tag = le16_to_cpu(le_acl->ace[i].tag); 166987da915Sopenharmony_ci acl->ace[i].perms = le16_to_cpu(le_acl->ace[i].perms); 167987da915Sopenharmony_ci acl->ace[i].id = le32_to_cpu(le_acl->ace[i].id); 168987da915Sopenharmony_ci } 169987da915Sopenharmony_ci return (0); 170987da915Sopenharmony_ci} 171987da915Sopenharmony_ci 172987da915Sopenharmony_ci/* 173987da915Sopenharmony_ci * Make a Posix ACL little endian 174987da915Sopenharmony_ci */ 175987da915Sopenharmony_ci 176987da915Sopenharmony_ciint cpu_to_le_acl(const struct POSIX_ACL *acl, size_t size, 177987da915Sopenharmony_ci struct LE_POSIX_ACL *le_acl) 178987da915Sopenharmony_ci{ 179987da915Sopenharmony_ci int i; 180987da915Sopenharmony_ci int cnt; 181987da915Sopenharmony_ci 182987da915Sopenharmony_ci le_acl->version = acl->version; 183987da915Sopenharmony_ci le_acl->flags = acl->flags; 184987da915Sopenharmony_ci le_acl->filler = const_cpu_to_le16(0); 185987da915Sopenharmony_ci cnt = (size - sizeof(struct POSIX_ACL)) / sizeof(struct POSIX_ACE); 186987da915Sopenharmony_ci for (i=0; i<cnt; i++) { 187987da915Sopenharmony_ci le_acl->ace[i].tag = cpu_to_le16(acl->ace[i].tag); 188987da915Sopenharmony_ci le_acl->ace[i].perms = cpu_to_le16(acl->ace[i].perms); 189987da915Sopenharmony_ci le_acl->ace[i].id = cpu_to_le32(acl->ace[i].id); 190987da915Sopenharmony_ci } 191987da915Sopenharmony_ci return (0); 192987da915Sopenharmony_ci} 193987da915Sopenharmony_ci 194987da915Sopenharmony_ci#endif 195987da915Sopenharmony_ci#endif 196987da915Sopenharmony_ci 197987da915Sopenharmony_ci/* 198987da915Sopenharmony_ci * Determine whether an extended attribute is mapped to 199987da915Sopenharmony_ci * internal data (original name in system namespace, or renamed) 200987da915Sopenharmony_ci */ 201987da915Sopenharmony_ci 202987da915Sopenharmony_cienum SYSTEMXATTRS ntfs_xattr_system_type(const char *name, 203987da915Sopenharmony_ci ntfs_volume *vol) 204987da915Sopenharmony_ci{ 205987da915Sopenharmony_ci struct XATTRNAME *p; 206987da915Sopenharmony_ci enum SYSTEMXATTRS ret; 207987da915Sopenharmony_ci#ifdef XATTR_MAPPINGS 208987da915Sopenharmony_ci const struct XATTRMAPPING *q; 209987da915Sopenharmony_ci#endif /* XATTR_MAPPINGS */ 210987da915Sopenharmony_ci 211987da915Sopenharmony_ci p = nf_ns_xattr_names; 212987da915Sopenharmony_ci while (p->name && strcmp(p->name,name)) 213987da915Sopenharmony_ci p++; 214987da915Sopenharmony_ci ret = p->xattr; 215987da915Sopenharmony_ci#ifdef XATTR_MAPPINGS 216987da915Sopenharmony_ci if (!p->name && vol && vol->xattr_mapping) { 217987da915Sopenharmony_ci q = vol->xattr_mapping; 218987da915Sopenharmony_ci while (q && strcmp(q->name,name)) 219987da915Sopenharmony_ci q = q->next; 220987da915Sopenharmony_ci if (q) 221987da915Sopenharmony_ci ret = q->xattr; 222987da915Sopenharmony_ci } 223987da915Sopenharmony_ci#else /* XATTR_MAPPINGS */ 224987da915Sopenharmony_ci if (!p->name 225987da915Sopenharmony_ci && vol 226987da915Sopenharmony_ci && vol->efs_raw 227987da915Sopenharmony_ci && !strcmp(nf_ns_alt_xattr_efsinfo,name)) 228987da915Sopenharmony_ci ret = XATTR_NTFS_EFSINFO; 229987da915Sopenharmony_ci#endif /* XATTR_MAPPINGS */ 230987da915Sopenharmony_ci return (ret); 231987da915Sopenharmony_ci} 232987da915Sopenharmony_ci 233987da915Sopenharmony_ci#ifdef XATTR_MAPPINGS 234987da915Sopenharmony_ci 235987da915Sopenharmony_ci/* 236987da915Sopenharmony_ci * Basic read from a user mapping file on another volume 237987da915Sopenharmony_ci */ 238987da915Sopenharmony_ci 239987da915Sopenharmony_cistatic int basicread(void *fileid, char *buf, size_t size, off_t offs __attribute__((unused))) 240987da915Sopenharmony_ci{ 241987da915Sopenharmony_ci return (read(*(int*)fileid, buf, size)); 242987da915Sopenharmony_ci} 243987da915Sopenharmony_ci 244987da915Sopenharmony_ci 245987da915Sopenharmony_ci/* 246987da915Sopenharmony_ci * Read from a user mapping file on current NTFS partition 247987da915Sopenharmony_ci */ 248987da915Sopenharmony_ci 249987da915Sopenharmony_cistatic int localread(void *fileid, char *buf, size_t size, off_t offs) 250987da915Sopenharmony_ci{ 251987da915Sopenharmony_ci return (ntfs_attr_data_read((ntfs_inode*)fileid, 252987da915Sopenharmony_ci AT_UNNAMED, 0, buf, size, offs)); 253987da915Sopenharmony_ci} 254987da915Sopenharmony_ci 255987da915Sopenharmony_ci/* 256987da915Sopenharmony_ci * Get a single mapping item from buffer 257987da915Sopenharmony_ci * 258987da915Sopenharmony_ci * Always reads a full line, truncating long lines 259987da915Sopenharmony_ci * Refills buffer when exhausted 260987da915Sopenharmony_ci * Returns pointer to item, or NULL when there is no more 261987da915Sopenharmony_ci * Note : errors are logged, but not returned 262987da915Sopenharmony_ci// TODO partially share with acls.c 263987da915Sopenharmony_ci */ 264987da915Sopenharmony_ci 265987da915Sopenharmony_cistatic struct XATTRMAPPING *getmappingitem(FILEREADER reader, void *fileid, 266987da915Sopenharmony_ci off_t *poffs, char *buf, int *psrc, s64 *psize) 267987da915Sopenharmony_ci{ 268987da915Sopenharmony_ci int src; 269987da915Sopenharmony_ci int dst; 270987da915Sopenharmony_ci char *pe; 271987da915Sopenharmony_ci char *ps; 272987da915Sopenharmony_ci char *pu; 273987da915Sopenharmony_ci enum SYSTEMXATTRS xattr; 274987da915Sopenharmony_ci int gotend; 275987da915Sopenharmony_ci char maptext[LINESZ]; 276987da915Sopenharmony_ci struct XATTRMAPPING *item; 277987da915Sopenharmony_ci 278987da915Sopenharmony_ci src = *psrc; 279987da915Sopenharmony_ci dst = 0; 280987da915Sopenharmony_ci do { 281987da915Sopenharmony_ci gotend = 0; 282987da915Sopenharmony_ci while ((src < *psize) 283987da915Sopenharmony_ci && (buf[src] != '\n')) { 284987da915Sopenharmony_ci /* ignore spaces */ 285987da915Sopenharmony_ci if ((dst < LINESZ) 286987da915Sopenharmony_ci && (buf[src] != '\r') 287987da915Sopenharmony_ci && (buf[src] != '\t') 288987da915Sopenharmony_ci && (buf[src] != ' ')) 289987da915Sopenharmony_ci maptext[dst++] = buf[src]; 290987da915Sopenharmony_ci src++; 291987da915Sopenharmony_ci } 292987da915Sopenharmony_ci if (src >= *psize) { 293987da915Sopenharmony_ci *poffs += *psize; 294987da915Sopenharmony_ci *psize = reader(fileid, buf, (size_t)BUFSZ, *poffs); 295987da915Sopenharmony_ci src = 0; 296987da915Sopenharmony_ci } else { 297987da915Sopenharmony_ci gotend = 1; 298987da915Sopenharmony_ci src++; 299987da915Sopenharmony_ci maptext[dst] = '\0'; 300987da915Sopenharmony_ci dst = 0; 301987da915Sopenharmony_ci } 302987da915Sopenharmony_ci } while (*psize && ((maptext[0] == '#') || !gotend)); 303987da915Sopenharmony_ci item = (struct XATTRMAPPING*)NULL; 304987da915Sopenharmony_ci if (gotend) { 305987da915Sopenharmony_ci /* decompose into system name and user name */ 306987da915Sopenharmony_ci ps = maptext; 307987da915Sopenharmony_ci pu = strchr(maptext,':'); 308987da915Sopenharmony_ci if (pu) { 309987da915Sopenharmony_ci *pu++ = 0; 310987da915Sopenharmony_ci pe = strchr(pu,':'); 311987da915Sopenharmony_ci if (pe) 312987da915Sopenharmony_ci *pe = 0; 313987da915Sopenharmony_ci /* check name validity */ 314987da915Sopenharmony_ci if ((strlen(pu) < 6) || strncmp(pu,"user.",5)) 315987da915Sopenharmony_ci pu = (char*)NULL; 316987da915Sopenharmony_ci xattr = ntfs_xattr_system_type(ps, 317987da915Sopenharmony_ci (ntfs_volume*)NULL); 318987da915Sopenharmony_ci if (xattr == XATTR_UNMAPPED) 319987da915Sopenharmony_ci pu = (char*)NULL; 320987da915Sopenharmony_ci } 321987da915Sopenharmony_ci if (pu) { 322987da915Sopenharmony_ci item = (struct XATTRMAPPING*)ntfs_malloc( 323987da915Sopenharmony_ci sizeof(struct XATTRMAPPING) 324987da915Sopenharmony_ci + strlen(pu)); 325987da915Sopenharmony_ci if (item) { 326987da915Sopenharmony_ci item->xattr = xattr; 327987da915Sopenharmony_ci strcpy(item->name,pu); 328987da915Sopenharmony_ci item->next = (struct XATTRMAPPING*)NULL; 329987da915Sopenharmony_ci } 330987da915Sopenharmony_ci } else { 331987da915Sopenharmony_ci ntfs_log_early_error("Bad xattr mapping item, aborting\n"); 332987da915Sopenharmony_ci } 333987da915Sopenharmony_ci } 334987da915Sopenharmony_ci *psrc = src; 335987da915Sopenharmony_ci return (item); 336987da915Sopenharmony_ci} 337987da915Sopenharmony_ci 338987da915Sopenharmony_ci/* 339987da915Sopenharmony_ci * Read xattr mapping file and split into their attribute. 340987da915Sopenharmony_ci * Parameters are kept in a chained list. 341987da915Sopenharmony_ci * Returns the head of list, if any 342987da915Sopenharmony_ci * Errors are logged, but not returned 343987da915Sopenharmony_ci * 344987da915Sopenharmony_ci * If an absolute path is provided, the mapping file is assumed 345987da915Sopenharmony_ci * to be located in another mounted file system, and plain read() 346987da915Sopenharmony_ci * are used to get its contents. 347987da915Sopenharmony_ci * If a relative path is provided, the mapping file is assumed 348987da915Sopenharmony_ci * to be located on the current file system, and internal IO 349987da915Sopenharmony_ci * have to be used since we are still mounting and we have not 350987da915Sopenharmony_ci * entered the fuse loop yet. 351987da915Sopenharmony_ci */ 352987da915Sopenharmony_ci 353987da915Sopenharmony_cistatic struct XATTRMAPPING *ntfs_read_xattr_mapping(FILEREADER reader, 354987da915Sopenharmony_ci void *fileid) 355987da915Sopenharmony_ci{ 356987da915Sopenharmony_ci char buf[BUFSZ]; 357987da915Sopenharmony_ci struct XATTRMAPPING *item; 358987da915Sopenharmony_ci struct XATTRMAPPING *current; 359987da915Sopenharmony_ci struct XATTRMAPPING *firstitem; 360987da915Sopenharmony_ci struct XATTRMAPPING *lastitem; 361987da915Sopenharmony_ci BOOL duplicated; 362987da915Sopenharmony_ci int src; 363987da915Sopenharmony_ci off_t offs; 364987da915Sopenharmony_ci s64 size; 365987da915Sopenharmony_ci 366987da915Sopenharmony_ci firstitem = (struct XATTRMAPPING*)NULL; 367987da915Sopenharmony_ci lastitem = (struct XATTRMAPPING*)NULL; 368987da915Sopenharmony_ci offs = 0; 369987da915Sopenharmony_ci size = reader(fileid, buf, (size_t)BUFSZ, (off_t)0); 370987da915Sopenharmony_ci if (size > 0) { 371987da915Sopenharmony_ci src = 0; 372987da915Sopenharmony_ci do { 373987da915Sopenharmony_ci item = getmappingitem(reader, fileid, &offs, 374987da915Sopenharmony_ci buf, &src, &size); 375987da915Sopenharmony_ci if (item) { 376987da915Sopenharmony_ci /* check no double mapping */ 377987da915Sopenharmony_ci duplicated = FALSE; 378987da915Sopenharmony_ci for (current=firstitem; current; current=current->next) 379987da915Sopenharmony_ci if ((current->xattr == item->xattr) 380987da915Sopenharmony_ci || !strcmp(current->name,item->name)) 381987da915Sopenharmony_ci duplicated = TRUE; 382987da915Sopenharmony_ci if (duplicated) { 383987da915Sopenharmony_ci free(item); 384987da915Sopenharmony_ci ntfs_log_early_error("Conflicting xattr mapping ignored\n"); 385987da915Sopenharmony_ci } else { 386987da915Sopenharmony_ci item->next = (struct XATTRMAPPING*)NULL; 387987da915Sopenharmony_ci if (lastitem) 388987da915Sopenharmony_ci lastitem->next = item; 389987da915Sopenharmony_ci else 390987da915Sopenharmony_ci firstitem = item; 391987da915Sopenharmony_ci lastitem = item; 392987da915Sopenharmony_ci } 393987da915Sopenharmony_ci } 394987da915Sopenharmony_ci } while (item); 395987da915Sopenharmony_ci } 396987da915Sopenharmony_ci return (firstitem); 397987da915Sopenharmony_ci} 398987da915Sopenharmony_ci 399987da915Sopenharmony_ci/* 400987da915Sopenharmony_ci * Build the extended attribute mappings to user namespace 401987da915Sopenharmony_ci * 402987da915Sopenharmony_ci * Note : no error is returned. If we refused mounting when there 403987da915Sopenharmony_ci * is an error it would be too difficult to fix the offending file 404987da915Sopenharmony_ci */ 405987da915Sopenharmony_ci 406987da915Sopenharmony_cistruct XATTRMAPPING *ntfs_xattr_build_mapping(ntfs_volume *vol, 407987da915Sopenharmony_ci const char *xattrmap_path) 408987da915Sopenharmony_ci{ 409987da915Sopenharmony_ci struct XATTRMAPPING *firstmapping; 410987da915Sopenharmony_ci struct XATTRMAPPING *mapping; 411987da915Sopenharmony_ci BOOL user_efs; 412987da915Sopenharmony_ci BOOL notfound; 413987da915Sopenharmony_ci ntfs_inode *ni; 414987da915Sopenharmony_ci int fd; 415987da915Sopenharmony_ci 416987da915Sopenharmony_ci firstmapping = (struct XATTRMAPPING*)NULL; 417987da915Sopenharmony_ci notfound = FALSE; 418987da915Sopenharmony_ci if (!xattrmap_path) 419987da915Sopenharmony_ci xattrmap_path = XATTRMAPPINGFILE; 420987da915Sopenharmony_ci if (xattrmap_path[0] == '/') { 421987da915Sopenharmony_ci fd = open(xattrmap_path,O_RDONLY); 422987da915Sopenharmony_ci if (fd > 0) { 423987da915Sopenharmony_ci firstmapping = ntfs_read_xattr_mapping(basicread, (void*)&fd); 424987da915Sopenharmony_ci close(fd); 425987da915Sopenharmony_ci } else 426987da915Sopenharmony_ci notfound = TRUE; 427987da915Sopenharmony_ci } else { 428987da915Sopenharmony_ci ni = ntfs_pathname_to_inode(vol, NULL, xattrmap_path); 429987da915Sopenharmony_ci if (ni) { 430987da915Sopenharmony_ci firstmapping = ntfs_read_xattr_mapping(localread, ni); 431987da915Sopenharmony_ci ntfs_inode_close(ni); 432987da915Sopenharmony_ci } else 433987da915Sopenharmony_ci notfound = TRUE; 434987da915Sopenharmony_ci } 435987da915Sopenharmony_ci if (notfound && strcmp(xattrmap_path, XATTRMAPPINGFILE)) { 436987da915Sopenharmony_ci ntfs_log_early_error("Could not open \"%s\"\n",xattrmap_path); 437987da915Sopenharmony_ci } 438987da915Sopenharmony_ci if (vol->efs_raw) { 439987da915Sopenharmony_ci user_efs = TRUE; 440987da915Sopenharmony_ci for (mapping=firstmapping; mapping; mapping=mapping->next) 441987da915Sopenharmony_ci if (mapping->xattr == XATTR_NTFS_EFSINFO) 442987da915Sopenharmony_ci user_efs = FALSE; 443987da915Sopenharmony_ci } else 444987da915Sopenharmony_ci user_efs = FALSE; 445987da915Sopenharmony_ci if (user_efs) { 446987da915Sopenharmony_ci mapping = (struct XATTRMAPPING*)ntfs_malloc( 447987da915Sopenharmony_ci sizeof(struct XATTRMAPPING) 448987da915Sopenharmony_ci + strlen(nf_ns_alt_xattr_efsinfo)); 449987da915Sopenharmony_ci if (mapping) { 450987da915Sopenharmony_ci mapping->next = firstmapping; 451987da915Sopenharmony_ci mapping->xattr = XATTR_NTFS_EFSINFO; 452987da915Sopenharmony_ci strcpy(mapping->name,nf_ns_alt_xattr_efsinfo); 453987da915Sopenharmony_ci firstmapping = mapping; 454987da915Sopenharmony_ci } 455987da915Sopenharmony_ci } 456987da915Sopenharmony_ci return (firstmapping); 457987da915Sopenharmony_ci} 458987da915Sopenharmony_ci 459987da915Sopenharmony_civoid ntfs_xattr_free_mapping(struct XATTRMAPPING *mapping) 460987da915Sopenharmony_ci{ 461987da915Sopenharmony_ci struct XATTRMAPPING *p, *q; 462987da915Sopenharmony_ci 463987da915Sopenharmony_ci p = mapping; 464987da915Sopenharmony_ci while (p) { 465987da915Sopenharmony_ci q = p->next; 466987da915Sopenharmony_ci free(p); 467987da915Sopenharmony_ci p = q; 468987da915Sopenharmony_ci } 469987da915Sopenharmony_ci} 470987da915Sopenharmony_ci 471987da915Sopenharmony_ci#endif /* XATTR_MAPPINGS */ 472987da915Sopenharmony_ci 473987da915Sopenharmony_ci/* 474987da915Sopenharmony_ci * Get an NTFS attribute into an extended attribute 475987da915Sopenharmony_ci * 476987da915Sopenharmony_ci * Returns the non-negative size of attribute if successful, 477987da915Sopenharmony_ci * or negative, with errno set, when fails 478987da915Sopenharmony_ci * Note : the size is returned even if no buffer is provided 479987da915Sopenharmony_ci * for returning the attribute, or if it is zero-sized. 480987da915Sopenharmony_ci */ 481987da915Sopenharmony_ci 482987da915Sopenharmony_ciint ntfs_xattr_system_getxattr(struct SECURITY_CONTEXT *scx, 483987da915Sopenharmony_ci enum SYSTEMXATTRS attr, 484987da915Sopenharmony_ci ntfs_inode *ni, ntfs_inode *dir_ni, 485987da915Sopenharmony_ci char *value, size_t size) 486987da915Sopenharmony_ci{ 487987da915Sopenharmony_ci int res; 488987da915Sopenharmony_ci int i; 489987da915Sopenharmony_ci#if POSIXACLS 490987da915Sopenharmony_ci#if __BYTE_ORDER == __BIG_ENDIAN 491987da915Sopenharmony_ci struct POSIX_ACL *acl; 492987da915Sopenharmony_ci#endif 493987da915Sopenharmony_ci#endif 494987da915Sopenharmony_ci 495987da915Sopenharmony_ci switch (attr) { 496987da915Sopenharmony_ci case XATTR_NTFS_ACL : 497987da915Sopenharmony_ci res = ntfs_get_ntfs_acl(scx, ni, value, size); 498987da915Sopenharmony_ci break; 499987da915Sopenharmony_ci#if POSIXACLS 500987da915Sopenharmony_ci#if __BYTE_ORDER == __BIG_ENDIAN 501987da915Sopenharmony_ci case XATTR_POSIX_ACC : 502987da915Sopenharmony_ci acl = (struct POSIX_ACL*)ntfs_malloc(size); 503987da915Sopenharmony_ci if (acl) { 504987da915Sopenharmony_ci res = ntfs_get_posix_acl(scx, ni, 505987da915Sopenharmony_ci nf_ns_xattr_posix_access, (char*)acl, size); 506987da915Sopenharmony_ci if (res > 0) { 507987da915Sopenharmony_ci if (cpu_to_le_acl(acl,res, 508987da915Sopenharmony_ci (struct LE_POSIX_ACL*)value)) 509987da915Sopenharmony_ci res = -errno; 510987da915Sopenharmony_ci } 511987da915Sopenharmony_ci free(acl); 512987da915Sopenharmony_ci } else 513987da915Sopenharmony_ci res = -errno; 514987da915Sopenharmony_ci break; 515987da915Sopenharmony_ci case XATTR_POSIX_DEF : 516987da915Sopenharmony_ci acl = (struct POSIX_ACL*)ntfs_malloc(size); 517987da915Sopenharmony_ci if (acl) { 518987da915Sopenharmony_ci res = ntfs_get_posix_acl(scx, ni, 519987da915Sopenharmony_ci nf_ns_xattr_posix_default, (char*)acl, size); 520987da915Sopenharmony_ci if (res > 0) { 521987da915Sopenharmony_ci if (cpu_to_le_acl(acl,res, 522987da915Sopenharmony_ci (struct LE_POSIX_ACL*)value)) 523987da915Sopenharmony_ci res = -errno; 524987da915Sopenharmony_ci } 525987da915Sopenharmony_ci free(acl); 526987da915Sopenharmony_ci } else 527987da915Sopenharmony_ci res = -errno; 528987da915Sopenharmony_ci break; 529987da915Sopenharmony_ci#else 530987da915Sopenharmony_ci case XATTR_POSIX_ACC : 531987da915Sopenharmony_ci res = ntfs_get_posix_acl(scx, ni, nf_ns_xattr_posix_access, 532987da915Sopenharmony_ci value, size); 533987da915Sopenharmony_ci break; 534987da915Sopenharmony_ci case XATTR_POSIX_DEF : 535987da915Sopenharmony_ci res = ntfs_get_posix_acl(scx, ni, nf_ns_xattr_posix_default, 536987da915Sopenharmony_ci value, size); 537987da915Sopenharmony_ci break; 538987da915Sopenharmony_ci#endif 539987da915Sopenharmony_ci#endif 540987da915Sopenharmony_ci case XATTR_NTFS_ATTRIB : 541987da915Sopenharmony_ci res = ntfs_get_ntfs_attrib(ni, value, size); 542987da915Sopenharmony_ci break; 543987da915Sopenharmony_ci case XATTR_NTFS_ATTRIB_BE : 544987da915Sopenharmony_ci res = ntfs_get_ntfs_attrib(ni, value, size); 545987da915Sopenharmony_ci if ((res == 4) && value) { 546987da915Sopenharmony_ci if (size >= 4) 547987da915Sopenharmony_ci fix_big_endian(value,4); 548987da915Sopenharmony_ci else 549987da915Sopenharmony_ci res = -EINVAL; 550987da915Sopenharmony_ci } 551987da915Sopenharmony_ci break; 552987da915Sopenharmony_ci case XATTR_NTFS_EFSINFO : 553987da915Sopenharmony_ci if (ni->vol->efs_raw) 554987da915Sopenharmony_ci res = ntfs_get_efs_info(ni, value, size); 555987da915Sopenharmony_ci else 556987da915Sopenharmony_ci res = -EPERM; 557987da915Sopenharmony_ci break; 558987da915Sopenharmony_ci case XATTR_NTFS_REPARSE_DATA : 559987da915Sopenharmony_ci res = ntfs_get_ntfs_reparse_data(ni, value, size); 560987da915Sopenharmony_ci break; 561987da915Sopenharmony_ci case XATTR_NTFS_OBJECT_ID : 562987da915Sopenharmony_ci res = ntfs_get_ntfs_object_id(ni, value, size); 563987da915Sopenharmony_ci break; 564987da915Sopenharmony_ci case XATTR_NTFS_DOS_NAME: 565987da915Sopenharmony_ci if (dir_ni) 566987da915Sopenharmony_ci res = ntfs_get_ntfs_dos_name(ni, dir_ni, value, size); 567987da915Sopenharmony_ci else 568987da915Sopenharmony_ci res = -errno; 569987da915Sopenharmony_ci break; 570987da915Sopenharmony_ci case XATTR_NTFS_TIMES: 571987da915Sopenharmony_ci res = ntfs_inode_get_times(ni, value, size); 572987da915Sopenharmony_ci break; 573987da915Sopenharmony_ci case XATTR_NTFS_TIMES_BE: 574987da915Sopenharmony_ci res = ntfs_inode_get_times(ni, value, size); 575987da915Sopenharmony_ci if ((res > 0) && value) { 576987da915Sopenharmony_ci for (i=0; (i+1)*sizeof(u64)<=(unsigned int)res; i++) 577987da915Sopenharmony_ci fix_big_endian(&value[i*sizeof(u64)], 578987da915Sopenharmony_ci sizeof(u64)); 579987da915Sopenharmony_ci } 580987da915Sopenharmony_ci break; 581987da915Sopenharmony_ci case XATTR_NTFS_CRTIME: 582987da915Sopenharmony_ci res = ntfs_inode_get_times(ni, value, 583987da915Sopenharmony_ci (size >= sizeof(u64) ? sizeof(u64) : size)); 584987da915Sopenharmony_ci break; 585987da915Sopenharmony_ci case XATTR_NTFS_CRTIME_BE: 586987da915Sopenharmony_ci res = ntfs_inode_get_times(ni, value, 587987da915Sopenharmony_ci (size >= sizeof(u64) ? sizeof(u64) : size)); 588987da915Sopenharmony_ci if ((res >= (int)sizeof(u64)) && value) 589987da915Sopenharmony_ci fix_big_endian(value,sizeof(u64)); 590987da915Sopenharmony_ci break; 591987da915Sopenharmony_ci case XATTR_NTFS_EA : 592987da915Sopenharmony_ci res = ntfs_get_ntfs_ea(ni, value, size); 593987da915Sopenharmony_ci break; 594987da915Sopenharmony_ci default : 595987da915Sopenharmony_ci errno = EOPNOTSUPP; 596987da915Sopenharmony_ci res = -errno; 597987da915Sopenharmony_ci break; 598987da915Sopenharmony_ci } 599987da915Sopenharmony_ci return (res); 600987da915Sopenharmony_ci} 601987da915Sopenharmony_ci 602987da915Sopenharmony_ci/* 603987da915Sopenharmony_ci * Set an NTFS attribute from an extended attribute 604987da915Sopenharmony_ci * 605987da915Sopenharmony_ci * Returns 0 if successful, 606987da915Sopenharmony_ci * non-zero, with errno set, when fails 607987da915Sopenharmony_ci */ 608987da915Sopenharmony_ci 609987da915Sopenharmony_ciint ntfs_xattr_system_setxattr(struct SECURITY_CONTEXT *scx, 610987da915Sopenharmony_ci enum SYSTEMXATTRS attr, 611987da915Sopenharmony_ci ntfs_inode *ni, ntfs_inode *dir_ni, 612987da915Sopenharmony_ci const char *value, size_t size, int flags) 613987da915Sopenharmony_ci{ 614987da915Sopenharmony_ci int res; 615987da915Sopenharmony_ci int i; 616987da915Sopenharmony_ci char buf[4*sizeof(u64)]; 617987da915Sopenharmony_ci#if POSIXACLS 618987da915Sopenharmony_ci#if __BYTE_ORDER == __BIG_ENDIAN 619987da915Sopenharmony_ci struct POSIX_ACL *acl; 620987da915Sopenharmony_ci#endif 621987da915Sopenharmony_ci#endif 622987da915Sopenharmony_ci 623987da915Sopenharmony_ci switch (attr) { 624987da915Sopenharmony_ci case XATTR_NTFS_ACL : 625987da915Sopenharmony_ci res = ntfs_set_ntfs_acl(scx, ni, value, size, flags); 626987da915Sopenharmony_ci break; 627987da915Sopenharmony_ci#if POSIXACLS 628987da915Sopenharmony_ci#if __BYTE_ORDER == __BIG_ENDIAN 629987da915Sopenharmony_ci case XATTR_POSIX_ACC : 630987da915Sopenharmony_ci acl = (struct POSIX_ACL*)ntfs_malloc(size); 631987da915Sopenharmony_ci if (acl) { 632987da915Sopenharmony_ci if (!le_acl_to_cpu((const struct LE_POSIX_ACL*)value, 633987da915Sopenharmony_ci size, acl)) { 634987da915Sopenharmony_ci res = ntfs_set_posix_acl(scx ,ni , 635987da915Sopenharmony_ci nf_ns_xattr_posix_access, 636987da915Sopenharmony_ci (char*)acl, size, flags); 637987da915Sopenharmony_ci } else 638987da915Sopenharmony_ci res = -errno; 639987da915Sopenharmony_ci free(acl); 640987da915Sopenharmony_ci } else 641987da915Sopenharmony_ci res = -errno; 642987da915Sopenharmony_ci break; 643987da915Sopenharmony_ci case XATTR_POSIX_DEF : 644987da915Sopenharmony_ci acl = (struct POSIX_ACL*)ntfs_malloc(size); 645987da915Sopenharmony_ci if (acl) { 646987da915Sopenharmony_ci if (!le_acl_to_cpu((const struct LE_POSIX_ACL*)value, 647987da915Sopenharmony_ci size, acl)) { 648987da915Sopenharmony_ci res = ntfs_set_posix_acl(scx ,ni , 649987da915Sopenharmony_ci nf_ns_xattr_posix_default, 650987da915Sopenharmony_ci (char*)acl, size, flags); 651987da915Sopenharmony_ci } else 652987da915Sopenharmony_ci res = -errno; 653987da915Sopenharmony_ci free(acl); 654987da915Sopenharmony_ci } else 655987da915Sopenharmony_ci res = -errno; 656987da915Sopenharmony_ci break; 657987da915Sopenharmony_ci#else 658987da915Sopenharmony_ci case XATTR_POSIX_ACC : 659987da915Sopenharmony_ci res = ntfs_set_posix_acl(scx ,ni , nf_ns_xattr_posix_access, 660987da915Sopenharmony_ci value, size, flags); 661987da915Sopenharmony_ci break; 662987da915Sopenharmony_ci case XATTR_POSIX_DEF : 663987da915Sopenharmony_ci res = ntfs_set_posix_acl(scx, ni, nf_ns_xattr_posix_default, 664987da915Sopenharmony_ci value, size, flags); 665987da915Sopenharmony_ci break; 666987da915Sopenharmony_ci#endif 667987da915Sopenharmony_ci#endif 668987da915Sopenharmony_ci case XATTR_NTFS_ATTRIB : 669987da915Sopenharmony_ci res = ntfs_set_ntfs_attrib(ni, value, size, flags); 670987da915Sopenharmony_ci break; 671987da915Sopenharmony_ci case XATTR_NTFS_ATTRIB_BE : 672987da915Sopenharmony_ci if (value && (size >= 4)) { 673987da915Sopenharmony_ci memcpy(buf,value,4); 674987da915Sopenharmony_ci fix_big_endian(buf,4); 675987da915Sopenharmony_ci res = ntfs_set_ntfs_attrib(ni, buf, 4, flags); 676987da915Sopenharmony_ci } else 677987da915Sopenharmony_ci res = ntfs_set_ntfs_attrib(ni, value, size, flags); 678987da915Sopenharmony_ci break; 679987da915Sopenharmony_ci case XATTR_NTFS_EFSINFO : 680987da915Sopenharmony_ci if (ni->vol->efs_raw) 681987da915Sopenharmony_ci res = ntfs_set_efs_info(ni, value, size, flags); 682987da915Sopenharmony_ci else { 683987da915Sopenharmony_ci errno = EPERM; 684987da915Sopenharmony_ci res = -EPERM; 685987da915Sopenharmony_ci } 686987da915Sopenharmony_ci break; 687987da915Sopenharmony_ci case XATTR_NTFS_REPARSE_DATA : 688987da915Sopenharmony_ci res = ntfs_set_ntfs_reparse_data(ni, value, size, flags); 689987da915Sopenharmony_ci break; 690987da915Sopenharmony_ci case XATTR_NTFS_OBJECT_ID : 691987da915Sopenharmony_ci res = ntfs_set_ntfs_object_id(ni, value, size, flags); 692987da915Sopenharmony_ci break; 693987da915Sopenharmony_ci case XATTR_NTFS_DOS_NAME: 694987da915Sopenharmony_ci if (dir_ni) 695987da915Sopenharmony_ci /* warning : this closes both inodes */ 696987da915Sopenharmony_ci res = ntfs_set_ntfs_dos_name(ni, dir_ni, value, 697987da915Sopenharmony_ci size, flags); 698987da915Sopenharmony_ci else { 699987da915Sopenharmony_ci errno = EINVAL; 700987da915Sopenharmony_ci res = -errno; 701987da915Sopenharmony_ci } 702987da915Sopenharmony_ci break; 703987da915Sopenharmony_ci case XATTR_NTFS_TIMES: 704987da915Sopenharmony_ci res = ntfs_inode_set_times(ni, value, size, flags); 705987da915Sopenharmony_ci break; 706987da915Sopenharmony_ci case XATTR_NTFS_TIMES_BE: 707987da915Sopenharmony_ci if (value && (size > 0) && (size <= 4*sizeof(u64))) { 708987da915Sopenharmony_ci memcpy(buf,value,size); 709987da915Sopenharmony_ci for (i=0; (i+1)*sizeof(u64)<=size; i++) 710987da915Sopenharmony_ci fix_big_endian(&buf[i*sizeof(u64)], 711987da915Sopenharmony_ci sizeof(u64)); 712987da915Sopenharmony_ci res = ntfs_inode_set_times(ni, buf, size, flags); 713987da915Sopenharmony_ci } else 714987da915Sopenharmony_ci res = ntfs_inode_set_times(ni, value, size, flags); 715987da915Sopenharmony_ci break; 716987da915Sopenharmony_ci case XATTR_NTFS_CRTIME: 717987da915Sopenharmony_ci res = ntfs_inode_set_times(ni, value, 718987da915Sopenharmony_ci (size >= sizeof(u64) ? sizeof(u64) : size), flags); 719987da915Sopenharmony_ci break; 720987da915Sopenharmony_ci case XATTR_NTFS_CRTIME_BE: 721987da915Sopenharmony_ci if (value && (size >= sizeof(u64))) { 722987da915Sopenharmony_ci memcpy(buf,value,sizeof(u64)); 723987da915Sopenharmony_ci fix_big_endian(buf,sizeof(u64)); 724987da915Sopenharmony_ci res = ntfs_inode_set_times(ni, buf, sizeof(u64), flags); 725987da915Sopenharmony_ci } else 726987da915Sopenharmony_ci res = ntfs_inode_set_times(ni, value, size, flags); 727987da915Sopenharmony_ci break; 728987da915Sopenharmony_ci case XATTR_NTFS_EA : 729987da915Sopenharmony_ci res = ntfs_set_ntfs_ea(ni, value, size, flags); 730987da915Sopenharmony_ci break; 731987da915Sopenharmony_ci default : 732987da915Sopenharmony_ci errno = EOPNOTSUPP; 733987da915Sopenharmony_ci res = -errno; 734987da915Sopenharmony_ci break; 735987da915Sopenharmony_ci } 736987da915Sopenharmony_ci return (res); 737987da915Sopenharmony_ci} 738987da915Sopenharmony_ci 739987da915Sopenharmony_ciint ntfs_xattr_system_removexattr(struct SECURITY_CONTEXT *scx, 740987da915Sopenharmony_ci enum SYSTEMXATTRS attr, 741987da915Sopenharmony_ci ntfs_inode *ni, ntfs_inode *dir_ni) 742987da915Sopenharmony_ci{ 743987da915Sopenharmony_ci int res; 744987da915Sopenharmony_ci 745987da915Sopenharmony_ci res = 0; 746987da915Sopenharmony_ci switch (attr) { 747987da915Sopenharmony_ci /* 748987da915Sopenharmony_ci * Removal of NTFS ACL, ATTRIB, EFSINFO or TIMES 749987da915Sopenharmony_ci * is never allowed 750987da915Sopenharmony_ci */ 751987da915Sopenharmony_ci case XATTR_NTFS_ACL : 752987da915Sopenharmony_ci case XATTR_NTFS_ATTRIB : 753987da915Sopenharmony_ci case XATTR_NTFS_ATTRIB_BE : 754987da915Sopenharmony_ci case XATTR_NTFS_EFSINFO : 755987da915Sopenharmony_ci case XATTR_NTFS_TIMES : 756987da915Sopenharmony_ci case XATTR_NTFS_TIMES_BE : 757987da915Sopenharmony_ci case XATTR_NTFS_CRTIME : 758987da915Sopenharmony_ci case XATTR_NTFS_CRTIME_BE : 759987da915Sopenharmony_ci res = -EPERM; 760987da915Sopenharmony_ci break; 761987da915Sopenharmony_ci#if POSIXACLS 762987da915Sopenharmony_ci case XATTR_POSIX_ACC : 763987da915Sopenharmony_ci case XATTR_POSIX_DEF : 764987da915Sopenharmony_ci if (ni) { 765987da915Sopenharmony_ci if (!ntfs_allowed_as_owner(scx, ni) 766987da915Sopenharmony_ci || ntfs_remove_posix_acl(scx, ni, 767987da915Sopenharmony_ci (attr == XATTR_POSIX_ACC ? 768987da915Sopenharmony_ci nf_ns_xattr_posix_access : 769987da915Sopenharmony_ci nf_ns_xattr_posix_default))) 770987da915Sopenharmony_ci res = -errno; 771987da915Sopenharmony_ci } else 772987da915Sopenharmony_ci res = -errno; 773987da915Sopenharmony_ci break; 774987da915Sopenharmony_ci#endif 775987da915Sopenharmony_ci case XATTR_NTFS_REPARSE_DATA : 776987da915Sopenharmony_ci if (ni) { 777987da915Sopenharmony_ci if (!ntfs_allowed_as_owner(scx, ni) 778987da915Sopenharmony_ci || ntfs_remove_ntfs_reparse_data(ni)) 779987da915Sopenharmony_ci res = -errno; 780987da915Sopenharmony_ci } else 781987da915Sopenharmony_ci res = -errno; 782987da915Sopenharmony_ci break; 783987da915Sopenharmony_ci case XATTR_NTFS_OBJECT_ID : 784987da915Sopenharmony_ci if (ni) { 785987da915Sopenharmony_ci if (!ntfs_allowed_as_owner(scx, ni) 786987da915Sopenharmony_ci || ntfs_remove_ntfs_object_id(ni)) 787987da915Sopenharmony_ci res = -errno; 788987da915Sopenharmony_ci } else 789987da915Sopenharmony_ci res = -errno; 790987da915Sopenharmony_ci break; 791987da915Sopenharmony_ci case XATTR_NTFS_DOS_NAME: 792987da915Sopenharmony_ci if (ni && dir_ni) { 793987da915Sopenharmony_ci if (ntfs_remove_ntfs_dos_name(ni,dir_ni)) 794987da915Sopenharmony_ci res = -errno; 795987da915Sopenharmony_ci /* ni and dir_ni have been closed */ 796987da915Sopenharmony_ci } else 797987da915Sopenharmony_ci res = -errno; 798987da915Sopenharmony_ci break; 799987da915Sopenharmony_ci case XATTR_NTFS_EA : 800987da915Sopenharmony_ci res = ntfs_remove_ntfs_ea(ni); 801987da915Sopenharmony_ci break; 802987da915Sopenharmony_ci default : 803987da915Sopenharmony_ci errno = EOPNOTSUPP; 804987da915Sopenharmony_ci res = -errno; 805987da915Sopenharmony_ci break; 806987da915Sopenharmony_ci } 807987da915Sopenharmony_ci return (res); 808987da915Sopenharmony_ci} 809