Ejemplo n.º 1
3
Archivo: uacl.c Proyecto: nshrine/jfacl
int setacl(const char *pathp, int size, aclent_t *aclpbuf)
{
	acl_t acl = NULL, default_acl = NULL, *current;
	acl_entry_t entry;
	acl_permset_t permset;
	int i, result, default_count = 0;
	
	struct stat st;
	
	if (stat(pathp, &st) != 0) {
		return -1;
	}
	
	for (i = 0; i < size; i++) {
		if (aclpbuf[i].a_type & ACL_DEFAULT) {
			default_count++;
		}
	}	
	acl = acl_init(size - default_count);
	if (default_count > 0) {
		default_acl = acl_init(default_count);
	}
	
	for (i = 0; i < size; i++) {		
		if (aclpbuf[i].a_type & ACL_DEFAULT) {						
			current = &default_acl;			
		} else {
			current = &acl;			
		}		
		acl_create_entry(current, &entry);		
		acl_get_permset(entry, &permset);		
		setmode(&permset, aclpbuf[i].a_perm);		
		acl_set_tag_type(entry, aclpbuf[i].a_type & ~ACL_DEFAULT);
		acl_set_qualifier(entry, &aclpbuf[i].a_id);
		acl_free(entry);
	}
	
	result = acl_set_file(pathp, ACL_TYPE_ACCESS, acl);
	if (result != 0 && (errno == ENOSYS || errno == ENOTSUP)) {
		if (default_acl != NULL) {
			return result;
		}
		
        mode_t mode;                                                                                                                                                             
        if (acl_equiv_mode(acl, &mode) == 0) {			
			result = chmod(pathp, mode);			
		}
	} else if ((result == 0) && S_ISDIR(st.st_mode)) {
		if (default_acl == NULL) {
			result = acl_delete_def_file(pathp);
		} else {
			result = acl_set_file(pathp, ACL_TYPE_DEFAULT, default_acl);
			acl_free(default_acl);
		}
	}
	acl_free(acl);
	
	return result;
}
Ejemplo n.º 2
0
/**
* creates a new acl_entry_t given acl and acl_entry
* acl: ptr to acl to add to
* acl_entry: where to get tag,qualifier, and perms
* returns status
**/
_BOOL acl_create(acl_t *acl,acl_entry_in *entry_in){
  acl_entry_t entry; //create the entry
  if((acl_create_entry(acl,&entry))!=ACL_OK)
    return FALSE;
  //set the tag
  if((acl_set_tag_type(entry,entry_in->tag))!=ACL_OK)
    return FALSE;
  //set the qualifier if necessary
  if(entry_in->tag == ACL_USER)
    if(acl_set_qualifier(entry,&entry_in->qualifier.u_qual)!=ACL_OK)
      return FALSE;
  else if(entry_in->tag == ACL_GROUP)
    if(acl_set_qualifier(entry,&entry_in->qualifier.g_qual)!=ACL_OK)
      return FALSE;

  if(!acl_update_permset(&entry,entry_in))
    return FALSE;
  return TRUE;
}
Ejemplo n.º 3
0
static int fix_acl(int fd, uid_t uid) {

#ifdef HAVE_ACL
        _cleanup_(acl_freep) acl_t acl = NULL;
        acl_entry_t entry;
        acl_permset_t permset;

        assert(fd >= 0);

        if (uid <= SYSTEM_UID_MAX)
                return 0;

        /* Make sure normal users can read (but not write or delete)
         * their own coredumps */

        acl = acl_get_fd(fd);
        if (!acl) {
                log_error("Failed to get ACL: %m");
                return -errno;
        }

        if (acl_create_entry(&acl, &entry) < 0 ||
            acl_set_tag_type(entry, ACL_USER) < 0 ||
            acl_set_qualifier(entry, &uid) < 0) {
                log_error("Failed to patch ACL: %m");
                return -errno;
        }

        if (acl_get_permset(entry, &permset) < 0 ||
            acl_add_perm(permset, ACL_READ) < 0 ||
            calc_acl_mask_if_needed(&acl) < 0) {
                log_warning("Failed to patch ACL: %m");
                return -errno;
        }

        if (acl_set_fd(fd, acl) < 0) {
                log_error("Failed to apply ACL: %m");
                return -errno;
        }
#endif

        return 0;
}
Ejemplo n.º 4
0
static int fix_acl(int fd, uid_t uid) {

#if HAVE_ACL
        _cleanup_(acl_freep) acl_t acl = NULL;
        acl_entry_t entry;
        acl_permset_t permset;
        int r;

        assert(fd >= 0);

        if (uid_is_system(uid) || uid_is_dynamic(uid) || uid == UID_NOBODY)
                return 0;

        /* Make sure normal users can read (but not write or delete)
         * their own coredumps */

        acl = acl_get_fd(fd);
        if (!acl)
                return log_error_errno(errno, "Failed to get ACL: %m");

        if (acl_create_entry(&acl, &entry) < 0 ||
            acl_set_tag_type(entry, ACL_USER) < 0 ||
            acl_set_qualifier(entry, &uid) < 0)
                return log_error_errno(errno, "Failed to patch ACL: %m");

        if (acl_get_permset(entry, &permset) < 0 ||
            acl_add_perm(permset, ACL_READ) < 0)
                return log_warning_errno(errno, "Failed to patch ACL: %m");

        r = calc_acl_mask_if_needed(&acl);
        if (r < 0)
                return log_warning_errno(r, "Failed to patch ACL: %m");

        if (acl_set_fd(fd, acl) < 0)
                return log_error_errno(errno, "Failed to apply ACL: %m");
#endif

        return 0;
}
int
acl_readonly_example(uuid_t *uuid)
{
	int fd;
	acl_t	acl;
	acl_entry_t ace;
	acl_permset_t perms;
	filesec_t fsec;

	/* initialize our ACL */
	if (NULL == (acl = acl_init(32)))
		err(1, "acl_init()");

	/*
	 * create an ACE
	 *
	 * acl_create_entry_np() has a position capability via the
	 * 'entry_index' argument (ACL_FIRST_ENTRY or ACL_LAST_ENTRY)
	 */
	if (0 != acl_create_entry(&acl, &ace))
		err(1, "acl_create_entry()");

	/* allow or deny */
	if (0 != acl_set_tag_type(ace, ACL_EXTENDED_ALLOW))
		err(1, "acl_set_tag_type()");

	/* associate this with our uuid */
	if (0 != acl_set_qualifier(ace, uuid))
		err(1, "acl_set_qualifier()");

	/* grant "read only" permissions */
	if (0 != acl_get_permset(ace, &perms))
		err(1, "acl_get_permset()");

	if (0 != acl_clear_perms(perms))
		err(1, "acl_clear_perms()");

	if (0 != acl_add_perm(perms, ROPERMS))
		err(1, "acl_add_perm()");

	if (0 != acl_set_permset(ace, perms))
		err(1, "acl_set_permset()");


	/* create a file security object */
	fsec = filesec_init();

	/* add the ACL to the security descriptor */
	filesec_set_property(fsec, FILESEC_ACL, &acl);
	acl_free(acl);

	/* turn off all other permissions on the file */
	filesec_set_property(fsec, FILESEC_MODE, 0);

	/* create a file using our ACL */
	fd = openx_np("foo", O_CREAT|O_EXCL|O_RDWR, fsec);

	/* clean up */
	filesec_free(fsec);
	if (-1 != fd )
		close(fd);

	return(fd);
}
Ejemplo n.º 6
0
acl_t
pfl_acl_from_xattr(const void *buf, size_t size)
{
	int i, entries;
	const struct acl_ea_header *h = buf;
	const struct acl_ea_entry *xe = PSC_AGP(h + 1, 0);
	unsigned int xperms;
	acl_permset_t permset;
	acl_entry_t e;
	acl_tag_t tag;
	acl_t a;

	if (size < sizeof(*h)) {
		errno = EINVAL;
		return (NULL);
	}
	if (le32toh(h->version) != ACL_EA_VERSION) {
		errno = EINVAL;
		return (NULL);
	}
	size -= sizeof(*h);
	if (size % sizeof(*xe)) {
		errno = EINVAL;
		return (NULL);
	}
	entries = size / sizeof(*xe);

	a = acl_init(entries);
	if (a == NULL)
		return (NULL);
	for (i = 0; i < entries; i++, xe++) {
		acl_create_entry(&a, &e);
		if (acl_get_permset(e, &permset) == -1)
			psclog_error("get_permset");
		acl_clear_perms(permset);

		xperms = le16toh(xe->perm);

		if (xperms & ACL_READ)
			acl_add_perm(permset, ACL_READ);
		if (xperms & ACL_WRITE)
			acl_add_perm(permset, ACL_WRITE);
		if (xperms & ACL_EXECUTE)
			acl_add_perm(permset, ACL_EXECUTE);
		if (acl_set_permset(e, permset) == -1)
			psclog_error("set_permset");

		acl_set_tag_type(e, tag = le16toh(xe->tag));

		switch (tag) {
		case ACL_USER: {
			uid_t uid = le32toh(xe->id);

			acl_set_qualifier(e, &uid);
			break;
		    }
		case ACL_GROUP: {
			gid_t gid = le32toh(xe->id);

			acl_set_qualifier(e, &gid);
			break;
		    }
		}
	}
	return (a);
}
Ejemplo n.º 7
0
static int set_facl(const char* filename, uid_t uid, int add)
{
	int get;
	acl_t acl;
	acl_entry_t entry = NULL;
	acl_entry_t e;
	acl_permset_t permset;
	int ret;

	/* don't touch ACLs for root */
	if (uid == 0)
		return 0;

	/* read current record */
	acl = acl_get_file(filename, ACL_TYPE_ACCESS);
	if (!acl)
		return -1;

	/* locate ACL_USER entry for uid */
	get = acl_get_entry(acl, ACL_FIRST_ENTRY, &e);
	while (get == 1) {
		acl_tag_t t;

		acl_get_tag_type(e, &t);
		if (t == ACL_USER) {
			uid_t *u;

			u = (uid_t*)acl_get_qualifier(e);
			if (u == NULL) {
				ret = -1;
				goto out;
			}
			if (*u == uid) {
				entry = e;
				acl_free(u);
				break;
			}
			acl_free(u);
		}

		get = acl_get_entry(acl, ACL_NEXT_ENTRY, &e);
	}

	/* remove ACL_USER entry for uid */
	if (!add) {
		if (entry == NULL) {
			ret = 0;
			goto out;
		}
		acl_delete_entry(acl, entry);
		goto update;
	}

	/* create ACL_USER entry for uid */
	if (entry == NULL) {
		ret = acl_create_entry(&acl, &entry);
		if (ret != 0)
			goto out;
		acl_set_tag_type(entry, ACL_USER);
		acl_set_qualifier(entry, &uid);
	}

	/* add permissions for uid */
	acl_get_permset(entry, &permset);
	acl_add_perm(permset, ACL_READ|ACL_WRITE);
update:
	/* update record */
	if (debug)
		printf("%c%u %s\n", add ? '+' : '-', uid, filename);
	acl_calc_mask(&acl);
	ret = acl_set_file(filename, ACL_TYPE_ACCESS, acl);
	if (ret != 0)
		goto out;
out:
	acl_free(acl);
	return ret;
}
Ejemplo n.º 8
0
Archivo: cert.c Proyecto: jelmer/cups
void
cupsdAddCert(int        pid,		/* I - Process ID */
             const char *username,	/* I - Username */
             int        type)		/* I - AuthType for username */
{
  int		i;			/* Looping var */
  cupsd_cert_t	*cert;			/* Current certificate */
  int		fd;			/* Certificate file */
  char		filename[1024];		/* Certificate filename */
  static const char hex[] = "0123456789ABCDEF";
					/* Hex constants... */


  cupsdLogMessage(CUPSD_LOG_DEBUG2,
                  "cupsdAddCert: Adding certificate for PID %d", pid);

 /*
  * Allocate memory for the certificate...
  */

  if ((cert = calloc(sizeof(cupsd_cert_t), 1)) == NULL)
    return;

 /*
  * Fill in the certificate information...
  */

  cert->pid  = pid;
  cert->type = type;
  strlcpy(cert->username, username, sizeof(cert->username));

  for (i = 0; i < 32; i ++)
    cert->certificate[i] = hex[CUPS_RAND() & 15];

 /*
  * Save the certificate to a file readable only by the User and Group
  * (or root and SystemGroup for PID == 0)...
  */

  snprintf(filename, sizeof(filename), "%s/certs/%d", StateDir, pid);
  unlink(filename);

  if ((fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0400)) < 0)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
                    "Unable to create certificate file %s - %s",
                    filename, strerror(errno));
    free(cert);
    return;
  }

  if (pid == 0)
  {
#ifdef HAVE_ACL_INIT
    acl_t		acl;		/* ACL information */
    acl_entry_t		entry;		/* ACL entry */
    acl_permset_t	permset;	/* Permissions */
#  ifdef HAVE_MBR_UID_TO_UUID
    uuid_t		group;		/* Group ID */
#  endif /* HAVE_MBR_UID_TO_UUID */
    static int		acls_not_supported = 0;
					/* Only warn once */
#endif /* HAVE_ACL_INIT */


   /*
    * Root certificate...
    */

    fchmod(fd, 0440);
    fchown(fd, RunUser, SystemGroupIDs[0]);

    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddCert: NumSystemGroups=%d",
                    NumSystemGroups);

#ifdef HAVE_ACL_INIT
    if (NumSystemGroups > 1)
    {
     /*
      * Set POSIX ACLs for the root certificate so that all system
      * groups can access it...
      */

      int	j;			/* Looping var */

#  ifdef HAVE_MBR_UID_TO_UUID
     /*
      * On MacOS X, ACLs use UUIDs instead of GIDs...
      */

      acl = acl_init(NumSystemGroups - 1);

      for (i = 1; i < NumSystemGroups; i ++)
      {
       /*
        * Add each group ID to the ACL...
	*/

        for (j = 0; j < i; j ++)
	  if (SystemGroupIDs[j] == SystemGroupIDs[i])
            break;

        if (j < i)
          continue;			/* Skip duplicate groups */

        acl_create_entry(&acl, &entry);
	acl_get_permset(entry, &permset);
	acl_add_perm(permset, ACL_READ_DATA);
	acl_set_tag_type(entry, ACL_EXTENDED_ALLOW);
	mbr_gid_to_uuid((gid_t)SystemGroupIDs[i], group);
	acl_set_qualifier(entry, &group);
	acl_set_permset(entry, permset);
      }

#  else
     /*
      * POSIX ACLs need permissions for owner, group, other, and mask
      * in addition to the rest of the system groups...
      */

      acl = acl_init(NumSystemGroups + 3);

      /* Owner */
      acl_create_entry(&acl, &entry);
      acl_get_permset(entry, &permset);
      acl_add_perm(permset, ACL_READ);
      acl_set_tag_type(entry, ACL_USER_OBJ);
      acl_set_permset(entry, permset);

      /* Group */
      acl_create_entry(&acl, &entry);
      acl_get_permset(entry, &permset);
      acl_add_perm(permset, ACL_READ);
      acl_set_tag_type(entry, ACL_GROUP_OBJ);
      acl_set_permset(entry, permset);

      /* Others */
      acl_create_entry(&acl, &entry);
      acl_get_permset(entry, &permset);
      acl_add_perm(permset, 0);
      acl_set_tag_type(entry, ACL_OTHER);
      acl_set_permset(entry, permset);

      /* Mask */
      acl_create_entry(&acl, &entry);
      acl_get_permset(entry, &permset);
      acl_add_perm(permset, ACL_READ);
      acl_set_tag_type(entry, ACL_MASK);
      acl_set_permset(entry, permset);

      for (i = 1; i < NumSystemGroups; i ++)
      {
       /*
        * Add each group ID to the ACL...
	*/

        for (j = 0; j < i; j ++)
	  if (SystemGroupIDs[j] == SystemGroupIDs[i])
            break;

        if (j < i)
          continue;			/* Skip duplicate groups */

        acl_create_entry(&acl, &entry);
	acl_get_permset(entry, &permset);
	acl_add_perm(permset, ACL_READ);
	acl_set_tag_type(entry, ACL_GROUP);
	acl_set_qualifier(entry, SystemGroupIDs + i);
	acl_set_permset(entry, permset);
      }

      if (acl_valid(acl))
      {
        char *text, *textptr;		/* Temporary string */

        cupsdLogMessage(CUPSD_LOG_ERROR, "ACL did not validate: %s",
	                strerror(errno));
        text = acl_to_text(acl, NULL);
	for (textptr = strchr(text, '\n');
	     textptr;
	     textptr = strchr(textptr + 1, '\n'))
	  *textptr = ',';

	cupsdLogMessage(CUPSD_LOG_ERROR, "ACL: %s", text);
	acl_free(text);
      }
#  endif /* HAVE_MBR_UID_TO_UUID */

      if (acl_set_fd(fd, acl))
      {
	if (errno != EOPNOTSUPP || !acls_not_supported)
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Unable to set ACLs on root certificate \"%s\" - %s",
			  filename, strerror(errno));

	if (errno == EOPNOTSUPP)
	  acls_not_supported = 1;
      }

      acl_free(acl);
    }
#endif /* HAVE_ACL_INIT */

    RootCertTime = time(NULL);
  }
  else
  {
   /*
    * CGI certificate...
    */

    fchmod(fd, 0400);
    fchown(fd, User, Group);
  }

  DEBUG_printf(("ADD pid=%d, username=%s, cert=%s\n", pid, username,
                cert->certificate));

  write(fd, cert->certificate, strlen(cert->certificate));
  close(fd);

 /*
  * Insert the certificate at the front of the list...
  */

  cert->next = Certs;
  Certs      = cert;
}
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
}
Ejemplo n.º 10
0
int devnode_acl(const char *path,
                bool flush,
                bool del, uid_t old_uid,
                bool add, uid_t new_uid) {

    acl_t acl;
    int r = 0;
    bool changed = false;

    assert(path);

    acl = acl_get_file(path, ACL_TYPE_ACCESS);
    if (!acl)
        return -errno;

    if (flush) {

        r = flush_acl(acl);
        if (r < 0)
            goto finish;
        if (r > 0)
            changed = true;

    } else if (del && old_uid > 0) {
        acl_entry_t entry;

        r = acl_find_uid(acl, old_uid, &entry);
        if (r < 0)
            goto finish;

        if (r > 0) {
            if (acl_delete_entry(acl, entry) < 0) {
                r = -errno;
                goto finish;
            }

            changed = true;
        }
    }

    if (add && new_uid > 0) {
        acl_entry_t entry;
        acl_permset_t permset;
        int rd, wt;

        r = acl_find_uid(acl, new_uid, &entry);
        if (r < 0)
            goto finish;

        if (r == 0) {
            if (acl_create_entry(&acl, &entry) < 0) {
                r = -errno;
                goto finish;
            }

            if (acl_set_tag_type(entry, ACL_USER) < 0 ||
                    acl_set_qualifier(entry, &new_uid) < 0) {
                r = -errno;
                goto finish;
            }
        }

        if (acl_get_permset(entry, &permset) < 0) {
            r = -errno;
            goto finish;
        }

        rd = acl_get_perm(permset, ACL_READ);
        if (rd < 0) {
            r = -errno;
            goto finish;
        }

        wt = acl_get_perm(permset, ACL_WRITE);
        if (wt < 0) {
            r = -errno;
            goto finish;
        }

        if (!rd || !wt) {

            if (acl_add_perm(permset, ACL_READ|ACL_WRITE) < 0) {
                r = -errno;
                goto finish;
            }

            changed = true;
        }
    }

    if (!changed)
        goto finish;

    if (acl_calc_mask(&acl) < 0) {
        r = -errno;
        goto finish;
    }

    if (acl_set_file(path, ACL_TYPE_ACCESS, acl) < 0) {
        r = -errno;
        goto finish;
    }

    r = 0;

finish:
    acl_free(acl);

    return r;
}
Ejemplo n.º 11
0
static int
set_acl(struct archive *a, int fd, const char *name,
        struct archive_acl *abstract_acl,
        acl_type_t acl_type, int ae_requested_type, const char *tname)
{
    acl_t		 acl;
    acl_entry_t	 acl_entry;
    acl_permset_t	 acl_permset;
#ifdef ACL_TYPE_NFS4
    acl_flagset_t	 acl_flagset;
    int		 r;
#endif
    int		 ret;
    int		 ae_type, ae_permset, ae_tag, ae_id;
    uid_t		 ae_uid;
    gid_t		 ae_gid;
    const char	*ae_name;
    int		 entries;
    int		 i;

    ret = ARCHIVE_OK;
    entries = archive_acl_reset(abstract_acl, ae_requested_type);
    if (entries == 0)
        return (ARCHIVE_OK);
    acl = acl_init(entries);
    while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
                            &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
        acl_create_entry(&acl, &acl_entry);

        switch (ae_tag) {
        case ARCHIVE_ENTRY_ACL_USER:
            acl_set_tag_type(acl_entry, ACL_USER);
            ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
            acl_set_qualifier(acl_entry, &ae_uid);
            break;
        case ARCHIVE_ENTRY_ACL_GROUP:
            acl_set_tag_type(acl_entry, ACL_GROUP);
            ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
            acl_set_qualifier(acl_entry, &ae_gid);
            break;
        case ARCHIVE_ENTRY_ACL_USER_OBJ:
            acl_set_tag_type(acl_entry, ACL_USER_OBJ);
            break;
        case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
            acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
            break;
        case ARCHIVE_ENTRY_ACL_MASK:
            acl_set_tag_type(acl_entry, ACL_MASK);
            break;
        case ARCHIVE_ENTRY_ACL_OTHER:
            acl_set_tag_type(acl_entry, ACL_OTHER);
            break;
#ifdef ACL_TYPE_NFS4
        case ARCHIVE_ENTRY_ACL_EVERYONE:
            acl_set_tag_type(acl_entry, ACL_EVERYONE);
            break;
#endif
        default:
            /* XXX */
            break;
        }

#ifdef ACL_TYPE_NFS4
        switch (ae_type) {
        case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
            acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW);
            break;
        case ARCHIVE_ENTRY_ACL_TYPE_DENY:
            acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_DENY);
            break;
        case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
            acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_AUDIT);
            break;
        case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
            acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALARM);
            break;
        case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
        case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
            // These don't translate directly into the system ACL.
            break;
        default:
            // XXX error handling here.
            break;
        }
#endif

        acl_get_permset(acl_entry, &acl_permset);
        acl_clear_perms(acl_permset);

        for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
            if (ae_permset & acl_perm_map[i].archive_perm)
                acl_add_perm(acl_permset,
                             acl_perm_map[i].platform_perm);
        }

#ifdef ACL_TYPE_NFS4
        // XXX acl_get_flagset_np on FreeBSD returns EINVAL for
        // non-NFSv4 ACLs
        r = acl_get_flagset_np(acl_entry, &acl_flagset);
        if (r == 0) {
            acl_clear_flags_np(acl_flagset);
            for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
                if (ae_permset & acl_inherit_map[i].archive_inherit)
                    acl_add_flag_np(acl_flagset,
                                    acl_inherit_map[i].platform_inherit);
            }
        }
#endif
    }

    /* Try restoring the ACL through 'fd' if we can. */
#if HAVE_ACL_SET_FD
    if (fd >= 0 && acl_type == ACL_TYPE_ACCESS && acl_set_fd(fd, acl) == 0)
        ret = ARCHIVE_OK;
    else
#else
#if HAVE_ACL_SET_FD_NP
    if (fd >= 0 && acl_set_fd_np(fd, acl, acl_type) == 0)
        ret = ARCHIVE_OK;
    else
#endif
#endif
#if HAVE_ACL_SET_LINK_NP
        if (acl_set_link_np(name, acl_type, acl) != 0) {
            archive_set_error(a, errno, "Failed to set %s acl", tname);
            ret = ARCHIVE_WARN;
        }
#else
        /* TODO: Skip this if 'name' is a symlink. */
        if (acl_set_file(name, acl_type, acl) != 0) {
            archive_set_error(a, errno, "Failed to set %s acl", tname);
            ret = ARCHIVE_WARN;
        }
#endif
    acl_free(acl);
    return (ret);
}
Ejemplo n.º 12
0
static int ParseEntityPosixLinux(char **str, acl_entry_t ace, int *is_mask)
{
    struct passwd *pwd;
    struct group *grp;
    acl_tag_t etype;
    size_t idsz;
    id_t id;
    char *ids;
    char *id_end;
    int result = true;
    int i;

    ids = NULL;

// TODO: Support numeric id in addition to (user/group) name ?

// Posix language: tag type, qualifier, permissions

    if (strncmp(*str, "user:"******"*", 2) == 0)
        {
            etype = ACL_USER_OBJ;
            id = 0;
        }
        else
        {
            etype = ACL_USER;
            pwd = getpwnam(ids);

            if (pwd == NULL)
            {
                Log(LOG_LEVEL_ERR, "Couldn't find user id for '%s'. (getpwnnam: %s)", ids, GetErrorStr());
                free(ids);
                return false;
            }

            id = pwd->pw_uid;
        }
    }
    else if (strncmp(*str, "group:", 6) == 0)
    {
        *str += 6;

        // create null-terminated string for entity id
        id_end = index(*str, ':');

        if (id_end == NULL)     // entity id already null-terminated
        {
            idsz = strlen(*str);
        }
        else                    // copy entity-id to new null-terminated string
        {
            idsz = id_end - *str;
        }

        ids = xmalloc(idsz + 1);
        for (i = 0; i < idsz; i++)
            ids[i] = (*str)[i];
        ids[idsz] = '\0';

        *str += idsz;

        // file group
        if (strncmp(ids, "*", 2) == 0)
        {
            etype = ACL_GROUP_OBJ;
            id = 0;             // TODO: Correct file group id ??
        }
        else
        {
            etype = ACL_GROUP;
            grp = getgrnam(ids);

            if (grp == NULL)
            {
                Log(LOG_LEVEL_ERR, "Error looking up group id for %s", ids);
                free(ids);
                return false;
            }

            id = grp->gr_gid;
        }

    }
    else if (strncmp(*str, "all:", 4) == 0)
    {
        *str += 3;
        etype = ACL_OTHER;
    }
    else if (strncmp(*str, "mask:", 5) == 0)
    {
        *str += 4;
        etype = ACL_MASK;
        *is_mask = true;
    }
    else
    {
        Log(LOG_LEVEL_ERR, "ace does not start with user:/group:/all:/mask:");
        return false;
    }

    if (acl_set_tag_type(ace, etype) != 0)
    {
        Log(LOG_LEVEL_ERR, "Could not set ACE tag type. (acl_set_tag_type: %s)", GetErrorStr());
        result = false;
    }
    else if (etype == ACL_USER || etype == ACL_GROUP)
    {
        if ((acl_set_qualifier(ace, &id)) != 0)
        {
            Log(LOG_LEVEL_ERR, "Could not set ACE qualifier. (acl_set_qualifier: %s)", GetErrorStr());
            result = false;
        }
    }

    if (ids != NULL)
    {
        free(ids);
    }

    return result;
}
Ejemplo n.º 13
0
int
do_set(
	const char *path_p,
	const struct stat *st,
	const seq_t seq)
{
	acl_t old_acl = NULL, old_default_acl = NULL;
	acl_t acl = NULL, default_acl = NULL;
	acl_t *xacl, *old_xacl;
	acl_entry_t ent;
	cmd_t cmd;
	int which_entry;
	int errors = 0, error;
	char *acl_text;
	int acl_modified = 0, default_acl_modified = 0;
	int acl_mask_provided = 0, default_acl_mask_provided = 0;

	/* Execute the commands in seq (read ACLs on demand) */
	error = seq_get_cmd(seq, SEQ_FIRST_CMD, &cmd);
	if (error == 0)
		return 0;
	while (error == 1) {
		if (cmd->c_type == ACL_TYPE_ACCESS) {
			xacl = &acl;
			old_xacl = &old_acl;
			acl_modified = 1;
			if (cmd->c_tag == ACL_MASK)
				acl_mask_provided = 1;
		} else {
			xacl = &default_acl;
			old_xacl = &old_default_acl;
			default_acl_modified = 1;
			if (cmd->c_tag == ACL_MASK)
				default_acl_mask_provided = 1;
		}

		RETRIEVE_ACL(cmd->c_type);

		/* Check for `X', and replace with `x' as appropriate. */
		if (cmd->c_perm & CMD_PERM_COND_EXECUTE) {
			cmd->c_perm &= ~CMD_PERM_COND_EXECUTE;
			if (S_ISDIR(st->st_mode) || has_execute_perms(*xacl))
				cmd->c_perm |= CMD_PERM_EXECUTE;
		}

		switch(cmd->c_cmd) {
			case CMD_ENTRY_REPLACE:
				ent = find_entry(*xacl, cmd->c_tag, cmd->c_id);
				if (!ent) {
					if (acl_create_entry(xacl, &ent) != 0)
						goto fail;
					acl_set_tag_type(ent, cmd->c_tag);
					if (cmd->c_id != ACL_UNDEFINED_ID)
						acl_set_qualifier(ent,
								  &cmd->c_id);
				}
				set_perm(ent, cmd->c_perm, ~cmd->c_perm);
				break;

			case CMD_ENTRY_ADD:
				ent = find_entry(*xacl, cmd->c_tag, cmd->c_id);
				if (ent)
					set_perm(ent, cmd->c_perm, 0);
				break;

			case CMD_ENTRY_SUBTRACT:
				ent = find_entry(*xacl, cmd->c_tag, cmd->c_id);
				if (ent)
					set_perm(ent, 0, cmd->c_perm);
				break;

			case CMD_REMOVE_ENTRY:
				ent = find_entry(*xacl, cmd->c_tag, cmd->c_id);
				if (ent)
					acl_delete_entry(*xacl, ent);
				else
					/* ignore */;
				break;

			case CMD_REMOVE_EXTENDED_ACL:
				remove_extended_entries(acl);
				break;

			case CMD_REMOVE_ACL:
				acl_free(*xacl);
				*xacl = acl_init(5);
				if (!*xacl)
					goto fail;
				break;

			default:
				errno = EINVAL;
				goto fail;
		}

		error = seq_get_cmd(seq, SEQ_NEXT_CMD, &cmd);
	}

	if (error < 0)
		goto fail;

	/* Try to fill in missing entries */
	if (default_acl && acl_entries(default_acl) != 0) {
		xacl = &acl;
		old_xacl = &old_acl;
	
		if (!find_entry(default_acl, ACL_USER_OBJ, ACL_UNDEFINED_ID)) {
			if (!acl)
				RETRIEVE_ACL(ACL_TYPE_ACCESS);
			clone_entry(acl, ACL_USER_OBJ,
			            &default_acl, ACL_USER_OBJ);
		}
		if (!find_entry(default_acl, ACL_GROUP_OBJ, ACL_UNDEFINED_ID)) {
			if (!acl)
				RETRIEVE_ACL(ACL_TYPE_ACCESS);
			clone_entry(acl, ACL_GROUP_OBJ,
			            &default_acl, ACL_GROUP_OBJ);
		}
		if (!find_entry(default_acl, ACL_OTHER, ACL_UNDEFINED_ID)) {
			if (!acl)
				RETRIEVE_ACL(ACL_TYPE_ACCESS);
			clone_entry(acl, ACL_OTHER,
			            &default_acl, ACL_OTHER);
		}
	}

	/* update mask entries and check if ACLs are valid */
	if (acl && acl_modified) {
		if (acl_equiv_mode(acl, NULL) != 0) {
			if (!acl_mask_provided &&
			    !find_entry(acl, ACL_MASK, ACL_UNDEFINED_ID))
				clone_entry(acl, ACL_GROUP_OBJ,
				            &acl, ACL_MASK);
			if (opt_recalculate != -1 &&
			    (!acl_mask_provided || opt_recalculate == 1))
				acl_calc_mask(&acl);
		}

		error = acl_check(acl, &which_entry);
		if (error < 0)
			goto fail;
		if (error > 0) {
			acl_text = acl_to_any_text(acl, NULL, ',', 0);
			fprintf(stderr, gettext("%s: %s: Malformed access ACL "
				"`%s': %s at entry %d\n"), progname, path_p,
				acl_text, acl_error(error), which_entry+1);
			acl_free(acl_text);
			errors++;
			goto cleanup;
		}
	}

	if (default_acl && acl_entries(default_acl) != 0 &&
	    default_acl_modified) {
		if (acl_equiv_mode(default_acl, NULL) != 0) {
			if (!default_acl_mask_provided &&
			    !find_entry(default_acl,ACL_MASK,ACL_UNDEFINED_ID))
				clone_entry(default_acl, ACL_GROUP_OBJ,
				            &default_acl, ACL_MASK);
			if (opt_recalculate != -1 &&
			    (!default_acl_mask_provided ||
			     opt_recalculate == 1))
				acl_calc_mask(&default_acl);
		}

		error = acl_check(default_acl, &which_entry);
		if (error < 0)
			goto fail;
		if (error > 0) {
			acl_text = acl_to_any_text(default_acl, NULL, ',', 0);
			fprintf(stderr, gettext("%s: %s: Malformed default ACL "
			                  "`%s': %s at entry %d\n"),
				progname, path_p, acl_text,
				acl_error(error), which_entry+1);
			acl_free(acl_text);
			errors++;
			goto cleanup;
		}
	}

	/* Only directores can have default ACLs */
	if (default_acl && !S_ISDIR(st->st_mode) && opt_recursive) {
		/* In recursive mode, ignore default ACLs for files */
		acl_free(default_acl);
		default_acl = NULL;
	}

	/* check which ACLs have changed */
	if (acl && old_acl && acl_cmp(old_acl, acl) == 0) {
		acl_free(acl);
		acl = NULL;
	}
	if ((default_acl && old_default_acl &&
	    acl_cmp(old_default_acl, default_acl) == 0)) {
		acl_free(default_acl);
		default_acl = NULL;
	}

	/* update the file system */
	if (opt_test) {
		print_test(stdout, path_p, st,
		           acl, default_acl);
		goto cleanup;
	}
	if (acl) {
		if (acl_set_file(path_p, ACL_TYPE_ACCESS, acl) != 0) {
			if (errno == ENOSYS || errno == ENOTSUP) {
				int saved_errno = errno;
				mode_t mode;

				if (acl_equiv_mode(acl, &mode) != 0) {
					errno = saved_errno;
					goto fail;
				} else if (chmod(path_p, mode) != 0)
					goto fail;
			} else
				goto fail;
		}
	}
	if (default_acl) {
		if (S_ISDIR(st->st_mode)) {
			if (acl_entries(default_acl) == 0) {
				if (acl_delete_def_file(path_p) != 0 &&
				    errno != ENOSYS && errno != ENOTSUP)
					goto fail;
			} else {
				if (acl_set_file(path_p, ACL_TYPE_DEFAULT,
						 default_acl) != 0)
					goto fail;
			}
		} else {
			if (acl_entries(default_acl) != 0) {
				fprintf(stderr, gettext(
						"%s: %s: Only directories "
						"can have default ACLs\n"),
					progname, path_p);
				errors++;
				goto cleanup;
			}
		}
	}

	error = 0;

cleanup:
	if (acl)
		acl_free(acl);
	if (old_acl)
		acl_free(old_acl);
	if (default_acl)
		acl_free(default_acl);
	if (old_default_acl)
		acl_free(old_default_acl);
	return errors;
	
fail:
	fprintf(stderr, "%s: %s: %s\n", progname, path_p, strerror(errno));
	errors++;
	goto cleanup;
}
Ejemplo n.º 14
0
static int acl_from_text_callback(acl_tag_t tag, int perms, const char *name, size_t name_len, void *params_casted)
{
	DEBUG("acl_from_text: tag: %d, name: %s, name_len: %lu\n", tag, name, (long unsigned)name_len);

	struct acl_from_text_params *params = (struct acl_from_text_params *)(params_casted);

	if (params->acl != NULL)
	{
		resolve resolve_func = params->custom_resolve;
		void *resolve_data = params->custom_resolve_data;

		uint32_t id = ((name == NULL || name_len == 0) ? ACL_UNDEFINED_ID : resolve_func(tag, name, name_len, resolve_data));

		switch (tag)
		{
		case ACL_USER:
		case ACL_GROUP:
			if (id == ACL_UNDEFINED_ID)
			{
				return -ENOENT;
			}
			break;
		}

		acl_entry_t entry = NULL;
		errno = 0;
		if (acl_create_entry(params->acl, &entry) != 0)
		{
			DEBUG("%d\n", 1);
			return -errno;
		}
		
		errno = 0;
		if (acl_set_tag_type(entry, tag) != 0)
		{
			DEBUG("%d\n", 2);
			return -errno;
		}

		acl_permset_t permset = NULL;

		errno = 0;
		if (acl_get_permset(entry, &permset) != 0)
		{
			return -errno;
		}

		if ((perms & ACL_READ) != 0)
		{
			errno = 0;
			if (acl_add_perm(permset, ACL_READ) != 0)
			{
				return -errno;
			}
		}

		if ((perms & ACL_WRITE) != 0)
		{
			errno = 0;
			if (acl_add_perm(permset, ACL_WRITE) != 0)
			{
				return -errno;
			}
		}

		if ((perms & ACL_EXECUTE) != 0)
		{
			errno = 0;
			if (acl_add_perm(permset, ACL_EXECUTE) != 0)
			{
				return -errno;
			}
		}
		
		errno = 0;
		if (acl_set_permset(entry, permset) != 0)
		{
			return -errno;
		}

		switch (tag)
		{
		case ACL_USER:
			{
			uid_t uid = (uid_t)(id);
			errno = 0;
			if (acl_set_qualifier(entry, (void *)&uid) != 0)
			{
				DEBUG("%d\n", 4);
				return -errno;
			}
			}
		case ACL_GROUP:
			{
			gid_t gid = (gid_t)(id);
			errno = 0;
			if (acl_set_qualifier(entry, (void *)&gid) != 0)
			{
				DEBUG("%d\n", 5);
				return -errno;
			}
			}
			break;
		}
	}

	++params->count;

	return 0;
}
Ejemplo n.º 15
0
int
main(int argc, char *argv[])
{
    Boolean recalcMask, useDefaultACL;
    Boolean modifyACL, removeACL, removeDefaultACL, checkValidity;
    int optCnt, j, opt, numEntries, en;
    acl_type_t type;
    char *aclSpec;
    acl_t acl;
    acl_entry_t entry;
    struct AccessControlEntry aclist[MAX_ENTRIES];

    if (argc < 2 || strcmp(argv[1], "--help") == 0)
        usageError(argv[0], NULL, FALSE);

    /* Parse command-line options */

    recalcMask = TRUE;
    useDefaultACL = FALSE;
    modifyACL = FALSE;
    removeACL = FALSE;
    checkValidity = FALSE;
    removeDefaultACL = FALSE;
    optCnt = 0;

    while ((opt = getopt(argc, argv, "m:x:kdnV:")) != -1) {
        switch (opt) {
        case 'm':
            modifyACL = TRUE;
            aclSpec = optarg;
            optCnt++;
            break;

        case 'x':
            removeACL = TRUE;
            aclSpec = optarg;
            optCnt++;
            break;

        case 'k':
            removeDefaultACL = TRUE;
            optCnt++;
            break;

        case 'V':
            checkValidity = TRUE;
            aclSpec = optarg;
            optCnt++;
            break;

        case 'd':
            useDefaultACL = TRUE;
            break;

        case 'n':
            recalcMask = FALSE;
            break;

        default:
            usageError(argv[0], "Bad option\n", TRUE);
            break;
        }
    }

    if (optCnt != 1)
        usageError(argv[0], "Specify exactly one of -m, -x, -k, or -V\n", TRUE);

    if (checkValidity && useDefaultACL)
        usageError(argv[0], "Can't specify -d with -V\n", TRUE);

    if (checkValidity) {
        if (parseACL(aclSpec, aclist, TRUE) == -1) {
            fatal("Bad ACL entry specification");
        } else {
            printf("ACL is valid\n");
            exit(EXIT_SUCCESS);
        }
    }

    if (modifyACL || removeACL) {
        numEntries = parseACL(aclSpec, aclist, modifyACL);
        if (numEntries == -1)
            usageError(argv[0], "Bad ACL specification\n", TRUE);
    }

    type = useDefaultACL ? ACL_TYPE_DEFAULT : ACL_TYPE_ACCESS;

    /* Perform the operation on each file argument */

    for (j = optind; j < argc; j++) {
        if (removeDefaultACL) {
            if (acl_delete_def_file(argv[j]) == -1)
                errExit("acl_delete_def_file: %s", argv[j]);

        } else if (modifyACL || removeACL) {

            acl = acl_get_file(argv[j], type);
            if (acl == NULL)
                errExit("acl_get_file");

            /* Apply each of the entries in 'aclist' to the
               current file */

            for (en = 0; en < numEntries; en++) {
                entry = findEntry(acl, aclist[en].tag, aclist[en].qual);

                if (removeACL) {
                    if (entry != NULL)
                        if (acl_delete_entry(acl, entry) == -1)
                            errExit("acl_delete_entry");

                } else {        /* modifyACL */

                    if (entry == NULL) {

                        /* Entry didn't exist in ACL -- create a new
                           entry with required tag and qualifier */

                        if (acl_create_entry(&acl, &entry) == -1)
                            errExit("acl_create_entry");
                        if (acl_set_tag_type(entry, aclist[en].tag) == -1)
                            errExit("acl_set_tag_type");
                        if (aclist[en].tag == ACL_USER ||
                                aclist[en].tag == ACL_GROUP)
                            if (acl_set_qualifier(entry,
                                        &aclist[en].qual) == -1)
                                errExit("acl_set_qualifier");
                    }

                    setPerms(entry, aclist[en].perms);
                }

                /* Recalculate the mask entry if requested */

                if (recalcMask)
                    if (acl_calc_mask(&acl) == -1)
                        errExit("acl_calc_mask");

                /* Update the file ACL */

                if (acl_valid(acl) == -1)
                    errExit("acl_valid");

                if (acl_set_file(argv[j], type, acl) == -1)
                    errExit("acl_set_file");
            }

            if (acl_free(acl) == -1)
                errExit("acl_free");
        } else {
            fatal("Bad logic!");
        }
    }

    exit(EXIT_SUCCESS);
}
Ejemplo n.º 16
0
/* Convert an acl entry in string form to an acl_entry_t */
int
parse_entry(char *entrybuf, acl_entry_t newent) {
	char *tok;
	char *pebuf;
	uuid_t *entryg;

	acl_tag_t	tag;
	acl_permset_t	perms;
	acl_flagset_t	flags;
	unsigned permcount = 0;
	unsigned pindex = 0;
	char *delimiter = " ";
	int nametype = NAME_EITHER;

	acl_get_permset(newent, &perms);
	acl_get_flagset_np(newent, &flags);

	pebuf = entrybuf;

	if (0 == strncmp(entrybuf, "user:"******"group:", 6)) {
		nametype = NAME_GROUP;
		pebuf += 6;
	}

	if (strchr(pebuf, ':')) /* User/Group names can have spaces */
		delimiter = ":";
	tok = strsep(&pebuf, delimiter);
	
	if ((tok == NULL) || *tok == '\0') {
		// errx(1, "Invalid entry format -- expected user or group name");
        fprintf(stderr, "chmod: Invalid entry format -- expected user or group name\n");
        pthread_exit(NULL);
	}

	/* parse the name into a qualifier */
	entryg = name_to_uuid(tok, nametype);

	tok = strsep(&pebuf, ": "); /* Stick with delimiter? */
	if ((tok == NULL) || *tok == '\0') {
		// errx(1, "Invalid entry format -- expected allow or deny");
        fprintf(stderr, "chmod: Invalid entry format -- expected allow or deny\n");
        pthread_exit(NULL);
	}

	/* is the verb 'allow' or 'deny'? */
	if (!strcmp(tok, "allow")) {
		tag = ACL_EXTENDED_ALLOW;
	} else if (!strcmp(tok, "deny")) {
		tag = ACL_EXTENDED_DENY;
	} else {
		// errx(1, "Unknown tag type '%s'", tok);
        fprintf(stderr, "chmod: Unknown tag type '%s'\n", tok);
        pthread_exit(NULL);
	}

	/* parse permissions */
	for (; (tok = strsep(&pebuf, ",")) != NULL;) {
		if (*tok != '\0') {
			/* is it a permission? */
			for (pindex = 0; acl_perms[pindex].name != NULL; pindex++) {
				if (!strcmp(acl_perms[pindex].name, tok)) {
					/* got one */
					acl_add_perm(perms, acl_perms[pindex].perm);
					permcount++;
					goto found;
				}
			}
			/* is it a flag? */
			for (pindex = 0; acl_flags[pindex].name != NULL; pindex++) {
				if (!strcmp(acl_flags[pindex].name, tok)) {
					/* got one */
					acl_add_flag_np(flags, acl_flags[pindex].flag);
					permcount++;
					goto found;
				}
			}
			// errx(1,"Invalid permission type '%s'", tok);
            fprintf(stderr,"chmod: Invalid permission type '%s'\n", tok);
            pthread_exit(NULL);
		found:
			continue;
		}
	}
	if (0 == permcount) {
		// errx(1, "No permissions specified");
        fprintf(stderr, "chmod: No permissions specified\n");
        pthread_exit(NULL);
	}
	acl_set_tag_type(newent, tag);
	acl_set_qualifier(newent, entryg);
	acl_set_permset(newent, perms);
	acl_set_flagset_np(newent, flags);
	free(entryg);
    entryg = NULL;

	return(0);
}
Ejemplo n.º 17
0
int fpm_unix_resolve_socket_premissions(struct fpm_worker_pool_s *wp) /* {{{ */
{
    struct fpm_worker_pool_config_s *c = wp->config;
#ifdef HAVE_FPM_ACL
    int n;

    /* uninitialized */
    wp->socket_acl  = NULL;
#endif
    wp->socket_uid = -1;
    wp->socket_gid = -1;
    wp->socket_mode = 0660;

    if (!c) {
        return 0;
    }

    if (c->listen_mode && *c->listen_mode) {
        wp->socket_mode = strtoul(c->listen_mode, 0, 8);
    }

#ifdef HAVE_FPM_ACL
    /* count the users and groups configured */
    n = 0;
    if (c->listen_acl_users && *c->listen_acl_users) {
        char *p;
        n++;
        for (p=strchr(c->listen_acl_users, ',') ; p ; p=strchr(p+1, ',')) {
            n++;
        }
    }
    if (c->listen_acl_groups && *c->listen_acl_groups) {
        char *p;
        n++;
        for (p=strchr(c->listen_acl_groups, ',') ; p ; p=strchr(p+1, ',')) {
            n++;
        }
    }
    /* if ACL configured */
    if (n) {
        acl_t acl;
        acl_entry_t entry;
        acl_permset_t perm;
        char *tmp, *p, *end;

        acl = acl_init(n);
        if (!acl) {
            zlog(ZLOG_SYSERROR, "[pool %s] cannot allocate ACL", wp->config->name);
            return -1;
        }
        /* Create USER ACL */
        if (c->listen_acl_users && *c->listen_acl_users) {
            struct passwd *pwd;

            tmp = estrdup(c->listen_acl_users);
            for (p=tmp ; p ; p=end) {
                if ((end = strchr(p, ','))) {
                    *end++ = 0;
                }
                pwd = getpwnam(p);
                if (pwd) {
                    zlog(ZLOG_DEBUG, "[pool %s] user '%s' have uid=%d", wp->config->name, p, pwd->pw_uid);
                } else {
                    zlog(ZLOG_SYSERROR, "[pool %s] cannot get uid for user '%s'", wp->config->name, p);
                    acl_free(acl);
                    efree(tmp);
                    return -1;
                }
                if (0 > acl_create_entry(&acl, &entry) ||
                        0 > acl_set_tag_type(entry, ACL_USER) ||
                        0 > acl_set_qualifier(entry, &pwd->pw_uid) ||
                        0 > acl_get_permset(entry, &perm) ||
                        0 > acl_clear_perms (perm) ||
                        0 > acl_add_perm (perm, ACL_READ) ||
                        0 > acl_add_perm (perm, ACL_WRITE)) {
                    zlog(ZLOG_SYSERROR, "[pool %s] cannot create ACL for user '%s'", wp->config->name, p);
                    acl_free(acl);
                    efree(tmp);
                    return -1;
                }
            }
            efree(tmp);
        }
        /* Create GROUP ACL */
        if (c->listen_acl_groups && *c->listen_acl_groups) {
            struct group *grp;

            tmp = estrdup(c->listen_acl_groups);
            for (p=tmp ; p ; p=end) {
                if ((end = strchr(p, ','))) {
                    *end++ = 0;
                }
                grp = getgrnam(p);
                if (grp) {
                    zlog(ZLOG_DEBUG, "[pool %s] group '%s' have gid=%d", wp->config->name, p, grp->gr_gid);
                } else {
                    zlog(ZLOG_SYSERROR, "[pool %s] cannot get gid for group '%s'", wp->config->name, p);
                    acl_free(acl);
                    efree(tmp);
                    return -1;
                }
                if (0 > acl_create_entry(&acl, &entry) ||
                        0 > acl_set_tag_type(entry, ACL_GROUP) ||
                        0 > acl_set_qualifier(entry, &grp->gr_gid) ||
                        0 > acl_get_permset(entry, &perm) ||
                        0 > acl_clear_perms (perm) ||
                        0 > acl_add_perm (perm, ACL_READ) ||
                        0 > acl_add_perm (perm, ACL_WRITE)) {
                    zlog(ZLOG_SYSERROR, "[pool %s] cannot create ACL for group '%s'", wp->config->name, p);
                    acl_free(acl);
                    efree(tmp);
                    return -1;
                }
            }
            efree(tmp);
        }
        if (c->listen_owner && *c->listen_owner) {
            zlog(ZLOG_WARNING, "[pool %s] ACL set, listen.owner = '%s' is ignored", wp->config->name, c->listen_owner);
        }
        if (c->listen_group && *c->listen_group) {
            zlog(ZLOG_WARNING, "[pool %s] ACL set, listen.group = '%s' is ignored", wp->config->name, c->listen_group);
        }
        wp->socket_acl  = acl;
        return 0;
    }
    /* When listen.users and listen.groups not configured, continue with standard right */
#endif

    if (c->listen_owner && *c->listen_owner) {
        struct passwd *pwd;

        pwd = getpwnam(c->listen_owner);
        if (!pwd) {
            zlog(ZLOG_SYSERROR, "[pool %s] cannot get uid for user '%s'", wp->config->name, c->listen_owner);
            return -1;
        }

        wp->socket_uid = pwd->pw_uid;
        wp->socket_gid = pwd->pw_gid;
    }

    if (c->listen_group && *c->listen_group) {
        struct group *grp;

        grp = getgrnam(c->listen_group);
        if (!grp) {
            zlog(ZLOG_SYSERROR, "[pool %s] cannot get gid for group '%s'", wp->config->name, c->listen_group);
            return -1;
        }
        wp->socket_gid = grp->gr_gid;
    }

    return 0;
}
Ejemplo n.º 18
0
static acl_t smb_acl_to_posix(const struct smb_acl_t *acl)
{
	acl_t result;
	int i;

	result = acl_init(acl->count);
	if (result == NULL) {
		DEBUG(10, ("acl_init failed\n"));
		return NULL;
	}

	for (i=0; i<acl->count; i++) {
		const struct smb_acl_entry *entry = &acl->acl[i];
		acl_entry_t e;
		acl_tag_t tag;

		if (acl_create_entry(&result, &e) != 0) {
			DEBUG(1, ("acl_create_entry failed: %s\n",
				  strerror(errno)));
			goto fail;
		}

		switch (entry->a_type) {
		case SMB_ACL_USER:
			tag = ACL_USER;
			break;
		case SMB_ACL_USER_OBJ:
			tag = ACL_USER_OBJ;
			break;
		case SMB_ACL_GROUP:
			tag = ACL_GROUP;
			break;
		case SMB_ACL_GROUP_OBJ:
			tag = ACL_GROUP_OBJ;
			break;
		case SMB_ACL_OTHER:
			tag = ACL_OTHER;
			break;
		case SMB_ACL_MASK:
			tag = ACL_MASK;
			break;
		default:
			DEBUG(1, ("Unknown tag value %d\n", entry->a_type));
			goto fail;
		}

		if (acl_set_tag_type(e, tag) != 0) {
			DEBUG(10, ("acl_set_tag_type(%d) failed: %s\n",
				   tag, strerror(errno)));
			goto fail;
		}

		switch (entry->a_type) {
		case SMB_ACL_USER:
			if (acl_set_qualifier(e, &entry->uid) != 0) {
				DEBUG(1, ("acl_set_qualifiier failed: %s\n",
					  strerror(errno)));
				goto fail;
			}
			break;
		case SMB_ACL_GROUP:
			if (acl_set_qualifier(e, &entry->gid) != 0) {
				DEBUG(1, ("acl_set_qualifiier failed: %s\n",
					  strerror(errno)));
				goto fail;
			}
			break;
		default: 	/* Shut up, compiler! :-) */
			break;
		}

		if (smb_acl_set_mode(e, entry->a_perm) != 0) {
			goto fail;
		}
	}

	if (acl_valid(result) != 0) {
		DEBUG(0, ("smb_acl_to_posix: ACL is invalid for set (%s)\n",
			  strerror(errno)));
		goto fail;
	}

	return result;

 fail:
	if (result != NULL) {
		acl_free(result);
	}
	return NULL;
}
Ejemplo n.º 19
0
acl_t
acl_from_text(const char *buf_p)
{
    int i, error = 0, need_tag, ug_tag;
    char *buf, *orig_buf;
    char *entry, *field, *sub;
    uuid_t *uu = NULL;
    struct passwd *tpass = NULL;
    struct group *tgrp = NULL;
    acl_entry_t acl_entry;
    acl_flagset_t flags = NULL;
    acl_permset_t perms = NULL;
    acl_tag_t tag;
    acl_t acl_ret;

    if (buf_p == NULL)
    {
	errno = EINVAL;
	return NULL;
    }

    if ((buf = strdup(buf_p)) == NULL)
	return NULL;

    if ((acl_ret = acl_init(1)) == NULL)
	return NULL;

    orig_buf = buf;

    /* global acl flags
     * format: !#acl <version> [<flags>]
     */
    if ((entry = strsep(&buf, "\n")) != NULL && *entry)
    {
	/* field 1: !#acl */
	field = strsep(&entry, " ");
	if (*field && strncmp(field, "!#acl", strlen("!#acl")))
	{
	    error = EINVAL;
	    goto exit;
	}

	/* field 2: <version>
	 * currently only accepts 1
	 */
	field = strsep(&entry, " ");
	errno = 0;
	if (!*field || strtol(field, NULL, 0) != 1)
	{
	    error = EINVAL;
	    goto exit;
	}

	/* field 3: <flags>
	 * optional
	 */
	if((field = strsep(&entry, " ")) != NULL && *field)
	{
	    acl_get_flagset_np(acl_ret, &flags);
	    while ((sub = strsep(&field, ",")) && *sub)
	    {
		for (i = 0; acl_flags[i].name != NULL; ++i)
		{
		    if (acl_flags[i].type & ACL_TYPE_ACL
			    && !strcmp(acl_flags[i].name, sub))
		    {
			acl_add_flag_np(flags, acl_flags[i].flag);
			break;
		    }
		}
		if (acl_flags[i].name == NULL)
		{
		    /* couldn't find flag */
		    error = EINVAL;
		    goto exit;
		}
	    }
	}
    } else {
	error = EINVAL;
	goto exit;
    }

    /* parse each acl line
     * format: <user|group>:
     *	    [<uuid>]:
     *	    [<user|group>]:
     *	    [<uid|gid>]:
     *	    <allow|deny>[,<flags>]
     *	    [:<permissions>[,<permissions>]]
     *
     * only one of the user/group identifies is required
     * the first one found is used
     */
    while ((entry = strsep(&buf, "\n")) && *entry)
    {
	need_tag = 1;
	ug_tag = -1;

	/* field 1: <user|group> */
	field = strsep(&entry, ":");

	if(uu)
	    bzero(uu, sizeof(uuid_t));
	else if((uu = calloc(1, sizeof(uuid_t))) == NULL)
	{
	    error = errno;
	    goto exit;
	}

	if(acl_create_entry(&acl_ret, &acl_entry))
	{
	    error = errno;
	    goto exit;
	}

	if (-1 == acl_get_flagset_np(acl_entry, &flags)
	 || -1 == acl_get_permset(acl_entry, &perms))
	{
	    error = errno;
	    goto exit;
	}

	switch(*field)
	{
	    case 'u':
		if(!strcmp(field, "user"))
		    ug_tag = ID_TYPE_UID;
		break;
	    case 'g':
		if(!strcmp(field, "group"))
		    ug_tag = ID_TYPE_GID;
		break;
	    default:
		error = EINVAL;
		goto exit;
	}

	/* field 2: <uuid> */
	if ((field = strsep(&entry, ":")) != NULL && *field)
	{
	    uuid_parse(field, *uu);
	    need_tag = 0;
	}

	/* field 3: <username|groupname> */
	if ((field = strsep(&entry, ":")) != NULL && *field && need_tag)
	{
	    switch(ug_tag)
	    {
		case ID_TYPE_UID:
		    if((tpass = getpwnam(field)) != NULL)
			if (mbr_uid_to_uuid(tpass->pw_uid, *uu) != 0)
			{
			    error = EINVAL;
			    goto exit;
			}
		    break;
		case ID_TYPE_GID:
		    if ((tgrp = getgrnam(field)) != NULL)
			if (mbr_gid_to_uuid(tgrp->gr_gid, *uu) != 0)
			{
			    error = EINVAL;
			    goto exit;
			}
		    break;
		default:
		    error = EINVAL;
		    goto exit;
	    }
	    need_tag = 0;
	}

	/* field 4: <uid|gid> */
	if ((field = strsep(&entry, ":")) != NULL && *field && need_tag)
	{
	    uid_t id;
	    error = 0;

	    if((id = strtol(field, NULL, 10)) == 0 && error)
	    {
		error = EINVAL;
		goto exit;
	    }

	    switch(ug_tag)
	    {
		case ID_TYPE_UID:
		    if((tpass = getpwuid((uid_t)id)) != NULL)
			if (mbr_uid_to_uuid(tpass->pw_uid, *uu) != 0)
			{
			    error = EINVAL;
			    goto exit;
			}
		    break;
		case ID_TYPE_GID:
		    if ((tgrp = getgrgid((gid_t)id)) != NULL)
			if (mbr_gid_to_uuid(tgrp->gr_gid, *uu) != 0)
			{
			    error = EINVAL;
			    goto exit;
			}
		    break;
	    }
	    need_tag = 0;
	}

	/* sanity check: nothing set as qualifier */
	if (need_tag)
	{
	    error = EINVAL;
	    goto exit;
	}

	/* field 5: <flags> */
	if((field = strsep(&entry, ":")) == NULL || !*field)
	{
	    error = EINVAL;
	    goto exit;
	}

	for (tag = 0; (sub = strsep(&field, ",")) && *sub;)
	{
	    if (!tag)
	    {
		if (!strcmp(sub, "allow"))
		    tag = ACL_EXTENDED_ALLOW;
		else if (!strcmp(sub, "deny"))
		    tag = ACL_EXTENDED_DENY;
		else {
		    error = EINVAL;
		    goto exit;
		}
		continue;
	    }

	    for (i = 0; acl_flags[i].name != NULL; ++i)
	    {
		if (acl_flags[i].type & (ACL_TYPE_FILE | ACL_TYPE_DIR)
			&& !strcmp(acl_flags[i].name, sub))
		{
		    acl_add_flag_np(flags, acl_flags[i].flag);
		    break;
		}
	    }
	    if (acl_flags[i].name == NULL)
	    {
		/* couldn't find perm */
		error = EINVAL;
		goto exit;
	    }
	}

	/* field 6: <perms> (can be empty) */
	if((field = strsep(&entry, ":")) != NULL && *field)
	{
	    while ((sub = strsep(&field, ",")) && *sub)
	    {
		for (i = 0; acl_perms[i].name != NULL; i++)
		{
		    if (acl_perms[i].type & (ACL_TYPE_FILE | ACL_TYPE_DIR)
			    && !strcmp(acl_perms[i].name, sub))
		    {
			acl_add_perm(perms, acl_perms[i].perm);
			break;
		    }
		}
		if (acl_perms[i].name == NULL)
		{
		    /* couldn't find perm */
		    error = EINVAL;
		    goto exit;
		}
	    }
	}
	acl_set_tag_type(acl_entry, tag);
	acl_set_qualifier(acl_entry, *uu);
    }
exit:
    if(uu)
	free(uu);
    free(orig_buf);
    if (error)
    {
	acl_free(acl_ret);
	acl_ret = NULL;
	errno = error;
    }
    return acl_ret;
}