20 #include "../config.h"
24 #include <sys/types.h>
32 #ifdef Libisofs_with_aaip_acL
36 #ifdef Libisofs_with_freebsd_extattR
37 #include <sys/extattr.h>
40 #include <sys/statvfs.h>
67 #ifdef Libisofs_with_aaip_acL
71 #ifdef Libisofs_with_freebsd_extattR
80 #ifdef Libisofs_with_freebsd_extattR
82 static int aaip_extattr_path_supp(
char *path,
int flag)
88 struct statvfs statvfs_buf;
90 ret = statvfs(path, &statvfs_buf);
93 return(!!(statvfs_buf.f_flag & MNT_EXTATTR));
128 #ifdef Libisofs_with_aaip_acL
134 if(flag & (1 << 15)) {
136 #ifdef Libisofs_with_aaip_acL
147 ret= stat(path, &stbuf);
149 ret= lstat(path, &stbuf);
152 if((stbuf.st_mode & S_IFMT) == S_IFLNK) {
162 #ifdef Libisofs_with_aaip_acL
164 acl= acl_get_file(path, ACL_TYPE_ACCESS);
167 if(errno == EOPNOTSUPP) {
178 *text= acl_to_text(acl, NULL);
193 if(!(ret & (7 | 64)))
195 if((*text)[0] == 0 || strcmp(*text,
"\n") == 0) {
196 #ifdef Libisofs_with_aaip_acL
209 #ifndef Libisofs_old_freebsd_acl_adapteR
211 #ifdef Libisofs_with_freebsd_extattR
217 static int aaip_extattr_make_list(
char *path,
int attrnamespace,
218 char **list, ssize_t *list_size,
int flag)
228 *list_size= extattr_list_file(path, attrnamespace, NULL, (
size_t) 0);
230 *list_size= extattr_list_link(path, attrnamespace, NULL, (
size_t) 0);
231 if(*list_size == -1) {
232 if(! aaip_extattr_path_supp(path, 0)) {
236 if(errno == EPERM && attrnamespace == EXTATTR_NAMESPACE_SYSTEM) {
244 *list= calloc(*list_size, 1);
248 *list_size= extattr_list_file(path, attrnamespace, *list,
249 (
size_t) *list_size);
251 *list_size= extattr_list_link(path, attrnamespace, *list,
252 (
size_t) *list_size);
264 static int aaip_extattr_make_namelist(
char *path,
char *attrnamespace,
265 char *list, ssize_t list_size,
266 char **namelist, ssize_t *namelist_size,
267 ssize_t *num_names,
int flag)
269 int i, j, len, new_bytes= 0, space_len;
270 char *new_list= NULL, *wpt;
279 space_len= strlen(attrnamespace);
280 for(i= 0; i < list_size; i+= len + 1) {
281 len= *((
unsigned char *) (list + i));
284 for(j= 0; j < len; j++)
285 if(list[i + 1 + j] == 0) {
290 new_bytes+= space_len + 1 + len + 1;
292 if((flag & 1) && *namelist_size > 0)
293 new_bytes+= *namelist_size;
294 new_list= calloc(new_bytes, 1);
298 if((flag & 1) && *namelist_size > 0) {
299 memcpy(new_list, *namelist, *namelist_size);
300 wpt= new_list + *namelist_size;
302 for(i= 0; i < list_size; i+= len + 1) {
303 len= *((
unsigned char *) (list + i));
305 for(j= 0; j < len; j++)
309 memcpy(wpt, attrnamespace, space_len);
312 memcpy(wpt, list + i + 1, len);
317 if((flag & 1) && *namelist != NULL)
320 *namelist_size= new_bytes;
325 static int get_single_attr(
char *path,
char *name,
size_t *value_length,
326 char **value_bytes,
int flag)
334 if(strncmp(name,
"user.", 5) == 0) {
335 attrnamespace= EXTATTR_NAMESPACE_USER;
340 attrnamespace= EXTATTR_NAMESPACE_SYSTEM;
345 value_ret= extattr_get_file(path, attrnamespace, namept, NULL, (
size_t) 0);
347 value_ret= extattr_get_link(path, attrnamespace, namept, NULL, (
size_t) 0);
351 *value_bytes= calloc(value_ret + 1, 1);
352 if(*value_bytes == NULL)
357 value_ret= extattr_get_file(path, attrnamespace, namept,
358 *value_bytes, (
size_t) value_ret);
360 value_ret= extattr_get_link(path, attrnamespace, namept,
361 *value_bytes, (
size_t) value_ret);
362 if(value_ret == -1) {
368 *value_length= value_ret;
400 size_t **value_lengths,
char ***values,
int flag)
403 ssize_t i, num_names= 0;
405 #ifdef Libisofs_with_aaip_acL
406 unsigned char *a_acl= NULL;
407 char *a_acl_text= NULL;
410 #ifdef Libisofs_with_freebsd_extattR
411 char *list= NULL, *user_list= NULL, *sys_list= NULL;
412 ssize_t value_ret, list_size= 0, user_list_size= 0;
413 ssize_t sys_list_size= 0;
416 int no_perm_for_system= 0;
418 if(flag & (1 << 15)) {
424 *value_lengths= NULL;
429 #ifdef Libisofs_with_freebsd_extattR
443 ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_USER,
444 &user_list, &user_list_size, flag & 32);
448 ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_SYSTEM,
449 &sys_list, &sys_list_size, flag & 32);
453 no_perm_for_system= 1;
457 ret= aaip_extattr_make_namelist(path,
"user", user_list, user_list_size,
458 &list, &list_size, &num_names, 0);
461 ret= aaip_extattr_make_namelist(path,
"system", sys_list, sys_list_size,
462 &list, &list_size, &num_names, 1);
469 #ifdef Libisofs_with_aaip_acL
473 #ifdef Libisofs_with_freebsd_extattR
482 (*names)= calloc(num_names,
sizeof(
char *));
483 (*value_lengths)= calloc(num_names,
sizeof(
size_t));
484 (*values)= calloc(num_names,
sizeof(
char *));
485 if(*names == NULL || *value_lengths == NULL || *values == NULL)
488 for(i= 0; i < num_names; i++) {
491 (*value_lengths)[i]= 0;
494 #ifdef Libisofs_with_freebsd_extattR
497 for(i= 0; i < list_size && (size_t) num_names - acl_names > *num_attrs;
498 i+= strlen(list + i) + 1) {
500 if(strncmp(list + i,
"user.", 5))
502 (*names)[(*num_attrs)++]= strdup(list + i);
503 if((*names)[(*num_attrs) - 1] == NULL)
507 for(i= 0; (size_t) i < *num_attrs; i++) {
508 value_ret= get_single_attr(path, (*names)[i], *value_lengths + i,
509 *values + i, flag & (8 | 32));
517 #ifdef Libisofs_with_aaip_acL
522 if(a_acl_text == NULL) {
524 ret= 1 + no_perm_for_system;
527 ret=
aaip_encode_acl(a_acl_text, (mode_t) 0, &a_acl_len, &a_acl, flag & 2);
534 (*names)[*num_attrs]= strdup(
"");
535 if((*names)[*num_attrs] == NULL)
537 (*values)[*num_attrs]= (
char *) a_acl;
539 (*value_lengths)[*num_attrs]= a_acl_len;
545 ret= 1 + no_perm_for_system;
547 #ifdef Libisofs_with_aaip_acL
550 if(a_acl_text != NULL)
553 #ifdef Libisofs_with_freebsd_extattR
556 if(user_list != NULL)
562 if(ret <= 0 || (flag & (1 << 15))) {
564 for(i= 0; (size_t) i < *num_attrs; i++)
569 if(*value_lengths != NULL)
570 free(*value_lengths);
571 *value_lengths= NULL;
572 if(*values != NULL) {
573 for(i= 0; (size_t) i < *num_attrs; i++)
612 size_t **value_lengths,
char ***values,
int flag)
615 ssize_t i, num_names;
617 #ifdef Libisofs_with_aaip_acL
619 unsigned char *a_acl= NULL;
620 char *acl_text= NULL;
623 if(flag & (1 << 15)) {
629 *value_lengths= NULL;
637 (*names)= calloc(num_names,
sizeof(
char *));
638 (*value_lengths)= calloc(num_names,
sizeof(
size_t));
639 (*values)= calloc(num_names,
sizeof(
char *));
640 if(*names == NULL || *value_lengths == NULL || *values == NULL)
643 for(i= 0; i < num_names; i++) {
646 (*value_lengths)[i]= 0;
649 #ifdef Libisofs_with_aaip_acL
656 ret=
aaip_encode_acl(acl_text, (mode_t) 0, &a_acl_len, &a_acl, flag & 2);
664 (*names)[*num_attrs]= strdup(
"");
665 if((*names)[*num_attrs] == NULL)
667 (*values)[*num_attrs]= (
char *) a_acl;
669 (*value_lengths)[*num_attrs]= a_acl_len;
677 #ifdef Libisofs_with_aaip_acL
684 if(ret <= 0 || (flag & (1 << 15))) {
686 for(i= 0; i < (ssize_t) *num_attrs; i++)
691 if(*value_lengths != NULL)
692 free(*value_lengths);
693 *value_lengths= NULL;
694 if(*values != NULL) {
695 for(i= 0; i < (ssize_t) *num_attrs; i++)
728 #ifdef Libisofs_with_aaip_acL
735 ret= stat(path, &stbuf);
737 ret= lstat(path, &stbuf);
740 if((stbuf.st_mode & S_IFMT) == S_IFLNK)
743 acl= acl_from_text(text);
752 ret= acl_set_file(path, ACL_TYPE_ACCESS, acl);
771 #ifndef Libisofs_old_freebsd_acl_adapteR
773 #ifdef Libisofs_with_freebsd_extattR
779 static int aaip_extattr_delete_names(
char *path,
int attrnamespace,
780 char *list, ssize_t list_size,
int flag)
784 ssize_t value_ret, i;
786 for(i= 0; i < list_size; i+= len + 1) {
787 len= *((
unsigned char *) (list + i));
789 strncpy(name, list + i + 1, len);
792 value_ret= extattr_delete_file(path, attrnamespace, name);
794 value_ret= extattr_delete_file(path, attrnamespace, name);
838 size_t *value_lengths,
char **values,
839 int *errnos,
int flag)
841 int ret, has_default_acl= 0, end_ret= 1;
842 size_t i, consumed, acl_text_fill, acl_idx= 0;
843 char *acl_text= NULL;
844 #ifdef Libisofs_with_freebsd_extattR
845 char *user_list= NULL, *sys_list= NULL, *namept, *old_value;
846 ssize_t user_list_size= 0, sys_list_size= 0, value_ret;
852 for(i= 0; i < num_attrs; i++)
855 #ifdef Libisofs_with_freebsd_extattR
858 ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_USER,
859 &user_list, &user_list_size, flag & 32);
862 ret= aaip_extattr_delete_names(path, EXTATTR_NAMESPACE_USER,
863 user_list, user_list_size, flag & 32);
867 ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_SYSTEM,
868 &sys_list, &sys_list_size, flag & 32);
871 ret= aaip_extattr_delete_names(path, EXTATTR_NAMESPACE_SYSTEM,
872 sys_list, sys_list_size, flag & 32);
880 for(i= 0; i < num_attrs; i++) {
881 if(names[i] == NULL || values[i] == NULL)
883 if(names[i][0] == 0) {
892 #ifdef Libisofs_with_freebsd_extattR
894 if(strncmp(names[i],
"user.", 5) == 0) {
895 attrnamespace= EXTATTR_NAMESPACE_USER;
896 namept= names[i] + 5;
897 }
else if(strncmp(names[i],
"isofs.", 6) == 0 || !(flag & 8)) {
899 }
else if(strncmp(names[i],
"system.", 7) == 0) {
900 attrnamespace= EXTATTR_NAMESPACE_SYSTEM;
901 namept= names[i] + 7;
909 value_ret= get_single_attr(path, names[i], &old_value_l,
910 &old_value, flag & (8 | 32));
911 if(value_ret > 0 && old_value_l == value_lengths[i]) {
912 if(memcmp(old_value, values[i], value_lengths[i]) == 0)
915 if(old_value != NULL)
920 ret= extattr_set_file(path, attrnamespace, namept,
921 values[i], value_lengths[i]);
923 ret= extattr_set_link(path, attrnamespace, namept,
924 values[i], value_lengths[i]);
935 if(strncmp(names[i],
"user.", 5) == 0)
937 else if(strncmp(names[i],
"isofs.", 6) == 0 || !(flag & 8))
951 {ret= end_ret;
goto ex;}
955 &consumed, NULL, 0, &acl_text_fill, 1);
960 acl_text= calloc(acl_text_fill, 1);
964 &consumed, acl_text, acl_text_fill, &acl_text_fill, 0);
969 has_default_acl= (ret == 2);
971 #ifdef Libisofs_with_aaip_acL
981 if(has_default_acl && !(flag & 64))
988 #ifdef Libisofs_with_freebsd_extattR
989 if(user_list != NULL)
1021 size_t *value_lengths,
char **values,
int flag)
1023 int ret, has_default_acl= 0, was_xattr= 0;
1024 size_t i, consumed, acl_text_fill;
1025 char *acl_text= NULL, *list= NULL;
1027 for(i= 0; i < num_attrs; i++) {
1028 if(names[i] == NULL || values[i] == NULL)
1030 if(names[i][0] == 0) {
1035 &consumed, NULL, 0, &acl_text_fill, 1);
1038 acl_text= calloc(acl_text_fill, 1);
1039 if(acl_text == NULL)
1042 &consumed, acl_text, acl_text_fill, &acl_text_fill, 0);
1045 has_default_acl= (ret == 2);
1047 #ifdef Libisofs_with_aaip_acL
1055 if(has_default_acl) {
1059 value_lengths[i] - consumed, &consumed,
1060 NULL, 0, &acl_text_fill, 1);
1063 acl_text= calloc(acl_text_fill, 1);
1064 if(acl_text == NULL)
1067 value_lengths[i] - consumed, &consumed,
1068 acl_text, acl_text_fill, &acl_text_fill, 0);
1079 if(strncmp(names[i],
"user.", 5))
1088 if(acl_text != NULL)
int aaip_set_attr_list(char *path, size_t num_attrs, char **names, size_t *value_lengths, char **values, int *errnos, int flag)
int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names, size_t **value_lengths, char ***values, int flag)
int aaip_set_acl_text(char *path, char *text, int flag)
int aaip_get_acl_text(char *path, char **text, int flag)
static void register_errno(int *errnos, int i, int in_errno)
int aaip_local_attr_support(int flag)
int aaip_encode_acl(char *acl_text, mode_t st_mode, size_t *result_len, unsigned char **result, int flag)
int aaip_cleanout_st_mode(char *acl_text, mode_t *in_st_mode, int flag)
int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed, char *acl_text, size_t acl_text_size, size_t *acl_text_fill, int flag)
#define ISO_AAIP_BAD_ATTR_NAME