/* 
 * sort the ACL and check it for validity
 *
 * [original comment from lib/sysacls.c:]
 * 
 * if it's a minimal ACL with only 4 entries then we
 * need to recalculate the mask permissions to make
 * sure that they are the same as the GROUP_OBJ
 * permissions as required by the UnixWare acl() system call.
 *
 * (note: since POSIX allows minimal ACLs which only contain
 * 3 entries - ie there is no mask entry - we should, in theory,
 * check for this and add a mask entry if necessary - however
 * we "know" that the caller of this interface always specifies
 * a mask, so in practice "this never happens" (tm) - if it *does*
 * happen aclsort() will fail and return an error and someone will
 * have to fix it...)
 */
static bool solaris_acl_sort(SOLARIS_ACL_T solaris_acl, int count)
{
	int fixmask = (count <= 4);

	if (aclsort(count, fixmask, solaris_acl) != 0) {
		errno = EINVAL;
		return False;
	}
	return True;
}
Пример #2
0
int compare_acl(acl_type* a1,acl_type* a2) {

  int i;
  if (a1==NULL && a2==NULL) {
    return RETOK;
  }
  if (a1==NULL || a2==NULL) {
    return RETFAIL;
  }

  if (a1->entries!=a2->entries) {
    return RETFAIL;
  }
  /* Sort em up. */
  aclsort(a1->entries,0,a1->acl);
  aclsort(a2->entries,0,a2->acl);
  for(i=0;i<a1->entries;i++){
    if (compare_single_acl(a1->acl+i,a2->acl+i)==RETFAIL) {
      return RETFAIL;
    }
  }
  return RETOK;
}
Пример #3
0
static int hpux_internal_aclsort(int acl_count, int calclass, HPUX_ACL_T aclp)
{
	struct hpux_acl_types acl_obj_count;
	int n_class_obj_perm = 0;
	int i, j;

	DEBUG(10,("Entering hpux_internal_aclsort. (calclass = %d)\n", calclass));

	if (hpux_aclsort_call_present()) {
		DEBUG(10, ("calling hpux aclsort\n"));
		return aclsort(acl_count, calclass, aclp);
	}

	DEBUG(10, ("using internal aclsort\n"));

	if(!acl_count) {
		DEBUG(10,("Zero acl count passed. Returning Success\n"));
		return 0;
	}

	if(aclp == NULL) {
		DEBUG(0,("Null ACL pointer in hpux_acl_sort. Returning Failure. \n"));
		return -1;
	}

	/* Count different types of ACLs in the ACLs array */

	hpux_count_obj(acl_count, aclp, &acl_obj_count);

	/* There should be only one entry each of type USER_OBJ, GROUP_OBJ, 
	 * CLASS_OBJ and OTHER_OBJ 
	 */

	if ( (acl_obj_count.n_user_obj  != 1) || 
		(acl_obj_count.n_group_obj != 1) || 
		(acl_obj_count.n_class_obj != 1) ||
		(acl_obj_count.n_other_obj != 1) ) 
	{
		DEBUG(0,("hpux_internal_aclsort: More than one entry or no entries for \
USER OBJ or GROUP_OBJ or OTHER_OBJ or CLASS_OBJ\n"));
		return -1;
	}
MateVFSResult 
file_set_acl (const char             *path,
	      const MateVFSFileInfo *info,
              MateVFSContext        *context)
{
#ifdef HAVE_SOLARIS_ACL
	GList           *acls;
	GList           *entry;
	guint            len;
	MateVFSResult   re;
	aclent_t        *new_aclp;
	aclent_t        *taclp;
	guint            aclp_i;
	gboolean         changed;

	if (info->acl == NULL) 
		return MATE_VFS_ERROR_BAD_PARAMETERS;

	acls = mate_vfs_acl_get_ace_list (info->acl);
	if (acls == NULL) return MATE_VFS_OK;

	changed = fixup_acl (info->acl, acls);	
	if (changed) {
		mate_vfs_acl_free_ace_list (acls);

		acls = mate_vfs_acl_get_ace_list (info->acl);
		if (acls == NULL) return MATE_VFS_OK;
	}

	len = g_list_length (acls);
	if (len <= 0) return MATE_VFS_OK;

	new_aclp = (aclent_t *) malloc (len * sizeof(aclent_t));
	if (new_aclp == NULL) return MATE_VFS_ERROR_NO_MEMORY;
	memset (new_aclp, 0, len * sizeof(aclent_t));

	aclp_i = 0;
	taclp  = new_aclp;
	for (entry=acls; entry != NULL; entry = entry->next) {
		MateVFSACE *ace = MATE_VFS_ACE(entry->data);
		
		re = translate_ace_into_aclent (ace, taclp);
		if (re != MATE_VFS_OK) continue;

		aclp_i++;
		taclp++;
	}

	/* Sort it out
	 */
 	re = aclsort (aclp_i, 0, (aclent_t *)new_aclp);
	if (re == -1) {
		g_free (new_aclp);
		return MATE_VFS_ERROR_INTERNAL;
	}		

	/* Commit it to the file system
	 */
	re = acl (path, SETACL, aclp_i, (aclent_t *)new_aclp); 
 	if (re < 0) {
		int err = errno;

		g_free (new_aclp);
		return aclerrno_to_vfserror(err);
	}

	g_free (new_aclp);
	return MATE_VFS_OK;
	
#elif defined(HAVE_POSIX_ACL)
	GList *acls;
	GList *entry;
	acl_t  acl_obj;
	acl_t  acl_obj_default;


	if (info->acl == NULL) 
		return MATE_VFS_ERROR_BAD_PARAMETERS;
	
	/* POSIX ACL object
	 */
	acl_obj_default = acl_get_file (path, ACL_TYPE_DEFAULT);     

	acl_obj = acl_get_file (path, ACL_TYPE_ACCESS);      
	if (acl_obj == NULL) return MATE_VFS_ERROR_GENERIC;

	/* Parse stored information
	 */
	acls = mate_vfs_acl_get_ace_list (info->acl);
	if (acls == NULL) return MATE_VFS_OK;

	for (entry=acls; entry != NULL; entry = entry->next) {
		MateVFSACE           *ace        = MATE_VFS_ACE(entry->data);
		gboolean               is_default = FALSE;
		const char            *id_str;
		MateVFSACLKind        kind;
		int                    id;

		int                    re;
		acl_tag_t              type;
		mode_t                 perms      = 0;
		acl_entry_t            new_entry  = NULL;
		acl_permset_t          permset    = NULL;
		
		id_str     = mate_vfs_ace_get_id (ace);
		kind       = mate_vfs_ace_get_kind (ace);
		is_default = mate_vfs_ace_get_inherit (ace);
		
		/* Perms
		 */
		if (mate_vfs_ace_check_perm (ace, MATE_VFS_ACL_READ))
			perms |= CMD_PERM_READ;
		else if (mate_vfs_ace_check_perm (ace, MATE_VFS_ACL_WRITE))
			perms |= CMD_PERM_WRITE;
		else if (mate_vfs_ace_check_perm (ace, MATE_VFS_ACL_EXECUTE))
			perms |= CMD_PERM_EXECUTE;
		
		/* Type
		 */
		switch (kind) {
		case MATE_VFS_ACL_USER:
			id   = string_to_uid (id_str);
			type = ACL_USER;			
			break;

		case MATE_VFS_ACL_GROUP:
			id   = string_to_gid (id_str);
			type = ACL_GROUP;
			break;

		case MATE_VFS_ACL_OTHER:
			type = ACL_OTHER;
			break;

		default:
			return MATE_VFS_ERROR_NOT_SUPPORTED;			
		}

		/* Add the entry
		 */
		new_entry = find_entry (acl_obj, type, id);
		if (new_entry == NULL) {
			/* new */
			if (is_default)
				re = acl_create_entry (&acl_obj_default, &new_entry);
			else
				re = acl_create_entry (&acl_obj, &new_entry);
			if (re != 0) return aclerrno_to_vfserror (errno);
			
			/* e_tag */
			re = acl_set_tag_type (new_entry, type);
			if (re != 0) return aclerrno_to_vfserror (errno);
			
			/* e_id */
			re = acl_set_qualifier (new_entry, &id);
			if (re != 0) return aclerrno_to_vfserror (errno);
		}

		/* e_perm */
		re = acl_get_permset (new_entry, &permset);
		if (re != 0) return aclerrno_to_vfserror (errno);
		set_permset (permset, perms);

		/* Fix it up
		 */
		if (is_default && (acl_obj_default != NULL)) {
			if (! find_entry (acl_obj_default, ACL_USER_OBJ, ACL_UNDEFINED_ID)) {
				clone_entry (acl_obj, ACL_USER_OBJ, &acl_obj_default, ACL_USER_OBJ);
			}
			
			if (! find_entry (acl_obj_default, ACL_GROUP_OBJ, ACL_UNDEFINED_ID)) {
				clone_entry (acl_obj, ACL_GROUP_OBJ, &acl_obj_default, ACL_GROUP_OBJ);
			}
			
			if (! find_entry (acl_obj_default, ACL_OTHER, ACL_UNDEFINED_ID)) {
				clone_entry (acl_obj, ACL_OTHER, &acl_obj_default, ACL_OTHER);
			}			
		}
		
		if (acl_equiv_mode (acl_obj, NULL) != 0) {

			if (! find_entry (acl_obj, ACL_MASK, ACL_UNDEFINED_ID)) {                       
				clone_entry (acl_obj, ACL_GROUP_OBJ, &acl_obj, ACL_MASK);
			}

			if (is_default)
				re = acl_calc_mask (&acl_obj_default);
			else 
				re = acl_calc_mask (&acl_obj);

			if (re != 0) return aclerrno_to_vfserror (errno);
		}
	}
		
	mate_vfs_acl_free_ace_list (acls);
	return MATE_VFS_OK;
#else
	return MATE_VFS_ERROR_NOT_SUPPORTED;
#endif
}