예제 #1
0
int sys_lsetxattr (const char *path, const char *uname, const void *value, size_t size, int flags)
{
	const char *name = prefix(uname);
#if defined(HAVE_LSETXATTR)
	return lsetxattr(path, name, value, size, flags);
#elif defined(HAVE_SETXATTR) && defined(XATTR_ADD_OPT)
	int options = XATTR_NOFOLLOW;
	return setxattr(path, name, value, size, 0, options);
#elif defined(LSETEA)
	return lsetea(path, name, value, size, flags);
#elif defined(HAVE_EXTATTR_SET_LINK)
	int retval = 0;
	if (flags) {
		/* Check attribute existence */
		retval = extattr_get_link(path, EXTATTR_NAMESPACE_USER, uname, NULL, 0);
		if (retval < 0) {
			/* REPLACE attribute, that doesn't exist */
			if (flags & XATTR_REPLACE && errno == ENOATTR) {
				errno = ENOATTR;
				return -1;
			}
			/* Ignore other errors */
		}
		else {
			/* CREATE attribute, that already exists */
			if (flags & XATTR_CREATE) {
				errno = EEXIST;
				return -1;
			}
		}
	}

	retval = extattr_set_link(path, EXTATTR_NAMESPACE_USER, uname, value, size);
	return (retval < 0) ? -1 : 0;
#elif defined(HAVE_ATTR_SET)
	int myflags = ATTR_DONTFOLLOW;
	char *attrname = strchr(name,'.') + 1;
	
	if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
	if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
	if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;

	return attr_set(path, attrname, (const char *)value, size, myflags);
#elif defined(HAVE_ATTROPEN)
	int ret = -1;
	int myflags = O_RDWR | AT_SYMLINK_NOFOLLOW;
	int attrfd;
	if (flags & XATTR_CREATE) myflags |= O_EXCL;
	if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
	attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE);
	if (attrfd >= 0) {
		ret = solaris_write_xattr(attrfd, value, size);
		close(attrfd);
	}
	return ret;
#else
	errno = ENOSYS;
	return -1;
#endif
}
예제 #2
0
파일: tape.c 프로젝트: Alkzndr/freebsd
/*
 * Set attributes for a symbolic link.
 */
static void
set_extattr_link(char *name, void *buf, int size)
{
	struct extattr *eap, *eaend;

	vprintf(stdout, "Set attributes for %s:", name);
	eaend = buf + size;
	for (eap = buf; eap < eaend; eap = EXTATTR_NEXT(eap)) {
		/*
		 * Make sure this entry is complete.
		 */
		if (EXTATTR_NEXT(eap) > eaend || eap->ea_length <= 0) {
			dprintf(stdout, "\n\t%scorrupted",
				eap == buf ? "" : "remainder ");
			break;
		}
		if (eap->ea_namespace == EXTATTR_NAMESPACE_EMPTY)
			continue;
		vprintf(stdout, "\n\t%s, (%d bytes), %*s",
			namespace_names[eap->ea_namespace], eap->ea_length,
			eap->ea_namelength, eap->ea_name);
		/*
		 * First we try the general attribute setting interface.
		 * However, some attributes can only be set by root or
		 * by using special interfaces (for example, ACLs).
		 */
		if (extattr_set_link(name, eap->ea_namespace, eap->ea_name,
		    EXTATTR_CONTENT(eap), EXTATTR_CONTENT_SIZE(eap)) != -1) {
			dprintf(stdout, " (set using extattr_set_link)");
			continue;
		}
		/*
		 * If the general interface refuses to set the attribute,
		 * then we try all the specialized interfaces that we
		 * know about.
		 */
		if (eap->ea_namespace == EXTATTR_NAMESPACE_SYSTEM &&
		    !strcmp(eap->ea_name, POSIX1E_ACL_ACCESS_EXTATTR_NAME)) {
			if (acl_set_link_np(name, ACL_TYPE_ACCESS,
			    EXTATTR_CONTENT(eap)) != -1) {
				dprintf(stdout, " (set using acl_set_link_np)");
				continue;
			}
		}
		if (eap->ea_namespace == EXTATTR_NAMESPACE_SYSTEM &&
		    !strcmp(eap->ea_name, POSIX1E_ACL_DEFAULT_EXTATTR_NAME)) {
			if (acl_set_link_np(name, ACL_TYPE_DEFAULT,
			    EXTATTR_CONTENT(eap)) != -1) {
				dprintf(stdout, " (set using acl_set_link_np)");
				continue;
			}
		}
		vprintf(stdout, " (unable to set)");
	}
	vprintf(stdout, "\n");
}
예제 #3
0
파일: lib_build.c 프로젝트: xattr/xattr
static ssize_t xattr_setxattr(const char *path, const char *name,
                              void *value, ssize_t size, u_int32_t position,
                              int options)
{
    int rv = 0;
    int nofollow;

    if (position != 0) {
        return -1;
    }

    nofollow = options & XATTR_XATTR_NOFOLLOW;
    options &= ~XATTR_XATTR_NOFOLLOW;

    if (options == XATTR_XATTR_CREATE ||
        options == XATTR_XATTR_REPLACE) {

        /* meh. FreeBSD doesn't really have this in its
         * API... Oh well.
         */
    }
    else if (options != 0) {
        return -1;
    }

    if (nofollow) {
        rv = extattr_set_link(path, EXTATTR_NAMESPACE_USER,
                                name, value, size);
    }
    else {
        rv = extattr_set_file(path, EXTATTR_NAMESPACE_USER,
                                name, value, size);
    }

    /* freebsd returns the written length on success, not zero. */
    if (rv >= 0) {
        return 0;
    }
    else {
        return rv;
    }
}
예제 #4
0
static PyObject *
lsetxattr_wrapper(PyObject *self, PyObject *args)
{
    const char *filename;
    const char *name;
    const char *value;
    int size;
    int ret;

    if (!PyArg_ParseTuple(args, "sss#", &filename, &name, &value, &size))
        return NULL;

#ifdef __FreeBSD__
    ret = extattr_set_link(filename, EXTATTR_NAMESPACE_USER, name, value, size);
#else
    ret = lsetxattr(filename, name, value, size, 0);
#endif
    if (ret == -1)
        ret = errno;
    return Py_BuildValue("i", ret);
}
예제 #5
0
int
main(int argc, char *argv[])
{
	char	*buf, *visbuf, *p;

	const char *options, *attrname;
	size_t	len;
	ssize_t	ret;
	int	 buflen, visbuflen, ch, error, i, arg_counter, attrnamespace,
		 minargc;

	int	flag_force = 0;
	int	flag_nofollow = 0;
	int	flag_null = 0;
	int	flag_quiet = 0;
	int	flag_string = 0;
	int	flag_hex = 0;

	visbuflen = buflen = 0;
	visbuf = buf = NULL;

	p = basename(argv[0]);
	if (p == NULL)
		p = argv[0];
	if (!strcmp(p, "getextattr")) {
		what = EAGET;
		options = "fhqsx";
		minargc = 3;
	} else if (!strcmp(p, "setextattr")) {
		what = EASET;
		options = "fhnq";
		minargc = 4;
	} else if (!strcmp(p, "rmextattr")) {
		what = EARM;
		options = "fhq";
		minargc = 3;
	} else if (!strcmp(p, "lsextattr")) {
		what = EALS;
		options = "fhq";
		minargc = 2;
	} else {
		usage();
	}

	while ((ch = getopt(argc, argv, options)) != -1) {
		switch (ch) {
		case 'f':
			flag_force = 1;
			break;
		case 'h':
			flag_nofollow = 1;
			break;
		case 'n':
			flag_null = 1;
			break;
		case 'q':
			flag_quiet = 1;
			break;
		case 's':
			flag_string = 1;
			break;
		case 'x':
			flag_hex = 1;
			break;
		case '?':
		default:
			usage();
		}
	}

	argc -= optind;
	argv += optind;

	if (argc < minargc)
		usage();

	error = extattr_string_to_namespace(argv[0], &attrnamespace);
	if (error)
		err(-1, "%s", argv[0]);
	argc--; argv++;

	if (what != EALS) {
		attrname = argv[0];
		argc--; argv++;
	} else
		attrname = NULL;

	if (what == EASET) {
		mkbuf(&buf, &buflen, strlen(argv[0]) + 1);
		strcpy(buf, argv[0]);
		argc--; argv++;
	}

	for (arg_counter = 0; arg_counter < argc; arg_counter++) {
		switch (what) {
		case EARM:
			if (flag_nofollow)
				error = extattr_delete_link(argv[arg_counter],
				    attrnamespace, attrname);
			else
				error = extattr_delete_file(argv[arg_counter],
				    attrnamespace, attrname);
			if (error >= 0)
				continue;
			break;
		case EASET:
			len = strlen(buf) + flag_null;
			if (flag_nofollow)
				ret = extattr_set_link(argv[arg_counter],
				    attrnamespace, attrname, buf, len);
			else
				ret = extattr_set_file(argv[arg_counter],
				    attrnamespace, attrname, buf, len);
			if (ret >= 0) {
				if ((size_t)ret != len && !flag_quiet) {
					warnx("Set %zd bytes of %zu for %s",
					    ret, len, attrname);
				}
				continue;
			}
			break;
		case EALS:
			if (flag_nofollow)
				ret = extattr_list_link(argv[arg_counter],
				    attrnamespace, NULL, 0);
			else
				ret = extattr_list_file(argv[arg_counter],
				    attrnamespace, NULL, 0);
			if (ret < 0)
				break;
			mkbuf(&buf, &buflen, ret);
			if (flag_nofollow)
				ret = extattr_list_link(argv[arg_counter],
				    attrnamespace, buf, buflen);
			else
				ret = extattr_list_file(argv[arg_counter],
				    attrnamespace, buf, buflen);
			if (ret < 0)
				break;
			if (!flag_quiet)
				printf("%s\t", argv[arg_counter]);
			for (i = 0; i < ret; i += ch + 1) {
			    /* The attribute name length is unsigned. */
			    ch = (unsigned char)buf[i];
			    printf("%s%*.*s", i ? "\t" : "",
				ch, ch, buf + i + 1);
			}
			if (!flag_quiet || ret > 0)
				printf("\n");
			continue;
		case EAGET:
			if (flag_nofollow)
				ret = extattr_get_link(argv[arg_counter],
				    attrnamespace, attrname, NULL, 0);
			else
				ret = extattr_get_file(argv[arg_counter],
				    attrnamespace, attrname, NULL, 0);
			if (ret < 0)
				break;
			mkbuf(&buf, &buflen, ret);
			if (flag_nofollow)
				ret = extattr_get_link(argv[arg_counter],
				    attrnamespace, attrname, buf, buflen);
			else
				ret = extattr_get_file(argv[arg_counter],
				    attrnamespace, attrname, buf, buflen);
			if (ret < 0)
				break;
			if (!flag_quiet)
				printf("%s\t", argv[arg_counter]);
			if (flag_string) {
				mkbuf(&visbuf, &visbuflen, ret * 4 + 1);
				strvisx(visbuf, buf, ret,
				    VIS_SAFE | VIS_WHITE);
				printf("\"%s\"\n", visbuf);
				continue;
			} else if (flag_hex) {
				for (i = 0; i < ret; i++)
					printf("%s%02x", i ? " " : "",
					    buf[i]);
				printf("\n");
				continue;
			} else {
				fwrite(buf, ret, 1, stdout);
				printf("\n");
				continue;
			}
		default:
			break;
		}
		if (!flag_quiet) 
			warn("%s: failed", argv[arg_counter]);
		if (flag_force)
			continue;
		return(1);
	}
	return (0);
}
예제 #6
0
파일: sysxattrs.c 프로젝트: JevonQ/rsync
int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size)
{
	return extattr_set_link(path, EXTATTR_NAMESPACE_USER, name, value, size);
}
예제 #7
0
파일: xattr.c 프로젝트: EmisFR/burp
static int do_set_xattr_bsd(struct asfd *asfd,
	const char *path,
	const char *xattrtext, size_t xlen, struct cntr *cntr)
{
	int ret=-1;
	size_t l=0;
	char *data=NULL;
	char *value=NULL;
	char *nspace=NULL;

	data=(char *)xattrtext;
	l=xlen;
	while(l>0)
	{
		ssize_t cnt;
		ssize_t vlen=0;
		int cnspace=0;
		char *name=NULL;

		if(!(nspace=get_next_xattr_str(asfd, &data, &l,
			cntr, &vlen, path))
		  || !(value=get_next_xattr_str(asfd, &data, &l,
			cntr, &vlen, path)))
				goto end;

		// Need to split the name into two parts.
		if(!(name=strchr(nspace, '.')))
		{
			logw(asfd, cntr,
			  "could not split %s into namespace and name on %s\n",
				nspace, path);
			goto end;
		}
		*name='\0';
		name++;

		if(extattr_string_to_namespace(nspace, &cnspace))
		{
			logw(asfd, cntr,
				"could not convert %s into namespace on %s\n",
				nspace, path);
			goto end;
		}

		//printf("set_link: %d %s %s %s\n", cnspace, nspace, name, value);
		if((cnt=extattr_set_link(path,
			cnspace, name, value, vlen))!=vlen)
		{
			logw(asfd, cntr,
				"extattr_set_link error on %s %zd!=%zd: %s\n",
				path, cnt, vlen, strerror(errno));
			goto end;
		}

		free_w(&nspace);
		free_w(&value);
	}
	ret=0;
end:
	free_w(&nspace);
	free_w(&value);
	return ret;
}
예제 #8
0
/* Bring the given attributes and/or ACLs into effect with the given file.
   @param flag          Bitfield for control purposes
                        bit0= decode and set ACLs
                        bit1= first clear all existing attributes of the file
                        bit2= do not set attributes other than ACLs
                        bit3= do not ignore eventual non-user attributes.
                              I.e. those with a name which does not begin
                              by "user."
                        bit5= in case of symbolic link: manipulate link target
                        bit6= tolerate inappropriate presence or absence of
                              directory default ACL
   @return              1 success
                       -1 error memory allocation
                       -2 error with decoding of ACL
                       -3 error with setting ACL
                       -4 error with setting attribute
                       -5 error with deleting attributes
                       -6 support of xattr not enabled at compile time
                       -7 support of ACL not enabled at compile time
                       -8 unsupported xattr namespace
    ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other::
*/
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
                       size_t *value_lengths, char **values, int flag)
{
 int ret, has_default_acl= 0;
 size_t i, consumed, acl_text_fill, acl_idx= 0;
 char *acl_text= NULL;
#ifdef Libisofs_with_freebsd_extattR
 char *user_list= NULL, *sys_list= NULL, *namept;
 ssize_t user_list_size= 0, sys_list_size= 0;
 int attrnamespace;
#endif

#ifdef Libisofs_with_freebsd_extattR

 if(flag & 2) { /* Delete all file attributes */
   ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_USER,
                               &user_list, &user_list_size, flag & 32);
   if(ret <= 0)
     {ret= -1; goto ex;}
   ret= aaip_extattr_delete_names(path, EXTATTR_NAMESPACE_USER,
                                  user_list, user_list_size, flag & 32);
   if(ret <= 0)
     {ret= -5; goto ex;}
   if(flag & 8) { 
     ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_SYSTEM,
                                 &sys_list, &sys_list_size, flag & 32);
     if(ret <= 0)
       {ret= -5; goto ex;}
     ret= aaip_extattr_delete_names(path, EXTATTR_NAMESPACE_SYSTEM,
                                  sys_list, sys_list_size, flag & 32);
     if(ret <= 0)
       {ret= -5; goto ex;}
   }
 }

#endif /* Libisofs_with_freebsd_extattR */

 for(i= 0; i < num_attrs; i++) {
   if(names[i] == NULL || values[i] == NULL)
 continue;
   if(names[i][0] == 0) { /* ACLs */
     if(flag & 1)
       acl_idx= i + 1;
 continue;
   }
   /* Extended Attribute */
   if(flag & 4)
 continue;

#ifdef Libisofs_with_freebsd_extattR

   if(strncmp(names[i], "user.", 5) == 0) {
     attrnamespace= EXTATTR_NAMESPACE_USER;
     namept= names[i] + 5;
   } else if(strncmp(names[i], "isofs.", 6) == 0 || !(flag & 8)) {
 continue;
   } else if(strncmp(names[i], "system.", 7) == 0) {
     attrnamespace= EXTATTR_NAMESPACE_SYSTEM;
     namept= names[i] + 7;
   } else {
     {ret= -8; goto ex;}
   }
   if(flag & 32)
     ret= extattr_set_file(path, attrnamespace, namept,
                           values[i], value_lengths[i]);
   else
     ret= extattr_set_link(path, attrnamespace, namept,
                           values[i], value_lengths[i]);
   if(ret == -1)
     {ret= -4; goto ex;}

#else

   if(strncmp(names[i], "user.", 5) == 0)
     ;
   else if(strncmp(names[i], "isofs.", 6) == 0 || !(flag & 8))
 continue;
   {ret= -6; goto ex;}

#endif /* Libisofs_with_freebsd_extattR */

 }

 /* Decode ACLs */
 if(acl_idx == 0)
   {ret= 1; goto ex;}
 i= acl_idx - 1; 

 ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
                      &consumed, NULL, 0, &acl_text_fill, 1);
 if(ret < -3)
   goto ex;
 if(ret <= 0)
   {ret= -2; goto ex;}
 acl_text= calloc(acl_text_fill, 1);
 if(acl_text == NULL) 
   {ret= -1; goto ex;}
 ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
                      &consumed, acl_text, acl_text_fill, &acl_text_fill, 0);
 if(ret < -3)
   goto ex;
 if(ret <= 0)
   {ret= -2; goto ex;} 
 has_default_acl= (ret == 2);

#ifdef Libisofs_with_aaip_acL
 ret= aaip_set_acl_text(path, acl_text, flag & (32 | 64));
 if(ret <= 0)
   {ret= -3; goto ex;}
#else
 {ret= -7; goto ex;}
#endif

 if(has_default_acl && !(flag & 64))
   {ret= -3; goto ex;}

 ret= 1;
ex:;
 if(acl_text != NULL)
   free(acl_text);
#ifdef Libisofs_with_freebsd_extattR
 if(user_list != NULL)
   free(user_list);
 if(sys_list != NULL)
   free(sys_list);
#endif /* Libisofs_with_freebsd_extattR */
 return(ret);
}