Esempio n. 1
0
static int smb_acl_set_mode(acl_entry_t entry, SMB_ACL_PERM_T perm)
{
        int ret;
        acl_permset_t permset;

	if ((ret = acl_get_permset(entry, &permset)) != 0) {
		return ret;
	}
        if ((ret = acl_clear_perms(permset)) != 0) {
                return ret;
	}
        if ((perm & SMB_ACL_READ) &&
	    ((ret = acl_add_perm(permset, ACL_READ)) != 0)) {
		return ret;
	}
        if ((perm & SMB_ACL_WRITE) &&
	    ((ret = acl_add_perm(permset, ACL_WRITE)) != 0)) {
		return ret;
	}
        if ((perm & SMB_ACL_EXECUTE) &&
	    ((ret = acl_add_perm(permset, ACL_EXECUTE)) != 0)) {
		return ret;
	}
        return acl_set_permset(entry, permset);
}
Esempio n. 2
0
File: uacl.c Progetto: nshrine/jfacl
static void setmode(acl_permset_t *permset_p, int mode)
{
	if (mode & ACL_READ) {
		acl_add_perm(*permset_p, ACL_READ);
	}

	if (mode & ACL_WRITE) {
		acl_add_perm(*permset_p, ACL_WRITE);
	}
	
	if (mode & ACL_EXECUTE) {
		acl_add_perm(*permset_p, ACL_EXECUTE);
	}
}
Esempio n. 3
0
/* Add the perms specified in modifier to rentry */
static int
merge_entry_perms(acl_entry_t rentry, acl_entry_t  modifier)
{
	acl_permset_t rperms, mperms;
	acl_flagset_t rflags, mflags;
	int i;

	if ((acl_get_permset(rentry, &rperms) != 0) ||
	    (acl_get_flagset_np(rentry, &rflags) != 0) ||
	    (acl_get_permset(modifier, &mperms) != 0) ||
	    (acl_get_flagset_np(modifier, &mflags) != 0))
		err(1, "error computing ACL modification");

	for (i = 0; acl_perms[i].name != NULL; i++) {
		if (acl_get_perm_np(mperms, acl_perms[i].perm))
			acl_add_perm(rperms, acl_perms[i].perm);
	}
	for (i = 0; acl_flags[i].name != NULL; i++) {
		if (acl_get_flag_np(mflags, acl_flags[i].flag))
			acl_add_flag_np(rflags, acl_flags[i].flag);
	}
	acl_set_permset(rentry, rperms);
	acl_set_flagset_np(rentry, rflags);
	return 0;
}
Esempio n. 4
0
/* Add the perms specified in modifier to rentry */
static int
merge_entry_perms(acl_entry_t rentry, acl_entry_t  modifier)
{
	acl_permset_t rperms, mperms;
	acl_flagset_t rflags, mflags;
	int i;

	if ((acl_get_permset(rentry, &rperms) != 0) ||
	    (acl_get_flagset_np(rentry, &rflags) != 0) ||
	    (acl_get_permset(modifier, &mperms) != 0) ||
        (acl_get_flagset_np(modifier, &mflags) != 0)) {
		// err(1, "error computing ACL modification");
        fprintf(stderr, "chmod: error computing ACL modification: %s\n", strerror(errno));
        pthread_exit(NULL);
    }

	for (i = 0; acl_perms[i].name != NULL; i++) {
		if (acl_get_perm_np(mperms, acl_perms[i].perm))
			acl_add_perm(rperms, acl_perms[i].perm);
	}
	for (i = 0; acl_flags[i].name != NULL; i++) {
		if (acl_get_flag_np(mflags, acl_flags[i].flag))
			acl_add_flag_np(rflags, acl_flags[i].flag);
	}
	acl_set_permset(rentry, rperms);
	acl_set_flagset_np(rentry, rflags);
	return 0;
}
static void
set_permset (acl_permset_t permset, mode_t perm)
{
        if (perm & CMD_PERM_READ)
                acl_add_perm (permset, ACL_READ);
        else
                acl_delete_perm (permset, ACL_READ);
	   
        if (perm & CMD_PERM_WRITE)
                acl_add_perm (permset, ACL_WRITE);
        else
                acl_delete_perm (permset, ACL_WRITE);
	   
        if (perm & CMD_PERM_EXECUTE)
                acl_add_perm (permset, ACL_EXECUTE);
        else
                acl_delete_perm (permset, ACL_EXECUTE);
}
Esempio n. 6
0
/**
* update a perm_set_t in entry to the one in aclentry
* entry: acl entry to change from in-memory
* acl_entry: where to retrieve new perms from
* returns status
**/
static _BOOL acl_update_perm(acl_entry_t *entry,acl_entry_in *entry_in){

  if(entry_in == NULL) return;

  acl_permset_t perm_set;
  if(acl_get_permset(*entry,&perm_set)!=ACL_OK)
    return FALSE;


  if(((entry_in->permset.nibble&READ) ? acl_add_perm(perm_set,ACL_READ)   : acl_delete_perm(perm_set,ACL_READ))!=ACL_OK)
    return FALSE;
  if(((entry_in->permset.nibble&WRITE)? acl_add_perm(perm_set,ACL_WRITE)  : acl_delete_perm(perm_set,ACL_WRITE))!=ACL_OK)
    return FALSE;
  if(((entry_in->permset.nibble&EXEC) ? acl_add_perm(perm_set,ACL_EXECUTE): acl_delete_perm(perm_set,ACL_EXECUTE))!=ACL_OK)
    return FALSE;

  if(acl_set_permset(*entry,perm_set)!=ACL_OK)
    return FALSE;
  return TRUE;
}
Esempio n. 7
0
static void
set_perm(
	acl_entry_t ent,
	mode_t add,
	mode_t remove)
{
	acl_permset_t set;

	acl_get_permset(ent, &set);
	if (remove & CMD_PERM_READ)
		acl_delete_perm(set, ACL_READ);
	if (remove & CMD_PERM_WRITE)
		acl_delete_perm(set, ACL_WRITE);
	if (remove & CMD_PERM_EXECUTE)
		acl_delete_perm(set, ACL_EXECUTE);
	if (add & CMD_PERM_READ)
		acl_add_perm(set, ACL_READ);
	if (add & CMD_PERM_WRITE)
		acl_add_perm(set, ACL_WRITE);
	if (add & CMD_PERM_EXECUTE)
		acl_add_perm(set, ACL_EXECUTE);
}
Esempio n. 8
0
static void
setPerms(acl_entry_t entry, int perms)
{
    acl_permset_t permset;

    if (acl_get_permset(entry, &permset) == -1)
        errExit("acl_get_permset");

    if (acl_clear_perms(permset) == -1)
        errExit("acl_clear_perms");

    if (perms & ACL_READ)
        if (acl_add_perm(permset, ACL_READ) == -1)
            errExit("acl_add_perm");
    if (perms & ACL_WRITE)
        if (acl_add_perm(permset, ACL_WRITE) == -1)
            errExit("acl_add_perm");
    if (perms & ACL_EXECUTE)
        if (acl_add_perm(permset, ACL_EXECUTE) == -1)
            errExit("acl_add_perm");

    if (acl_set_permset(entry, permset) == -1)
        errExit("acl_set_permset");
}
Esempio n. 9
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;
}
Esempio n. 10
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;
}
Esempio n. 11
0
File: cert.c Progetto: 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;
}
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;
}
Esempio n. 13
0
static int ParseModePosixLinux(char *mode, acl_permset_t perms)
{
    int retv;
    int more_entries;
    acl_perm_t perm;
    enum { add, del } op;

    op = add;

    if (*mode == '\0' || *mode == ':')
    {
        if (acl_clear_perms(perms) != 0)
        {
            Log(LOG_LEVEL_ERR, "Error clearing perms. (acl_clear_perms: %s)", GetErrorStr());
            return false;
        }
        else
        {
            return true;
        }
    }

    more_entries = true;

    while (more_entries)
    {
        switch (*mode)
        {
        case '+':
            op = add;
            mode++;
            break;

        case '-':
            op = del;
            mode++;
            break;

        case '=':
            mode++;
            // fallthrough

        default:
            // if mode does not start with + or -, we clear existing perms
            op = add;

            if (acl_clear_perms(perms) != 0)
            {
                Log(LOG_LEVEL_ERR, "Unable to clear ACL permissions. (acl_clear_perms: %s)", GetErrorStr());
                return false;
            }
        }

        // parse generic perms (they are 1-1 on Posix)

        while (*mode != '\0' && strchr(CF_VALID_GPERMS, *mode))
        {
            if (*mode == '\0')
            {
                break;
            }
            switch (*mode)
            {
            case 'r':
                perm = ACL_READ;
                break;

            case 'w':
                perm = ACL_WRITE;
                break;

            case 'x':
                perm = ACL_EXECUTE;
                break;

            default:
                Log(LOG_LEVEL_ERR, "No linux support for generic permission flag '%c'", *mode);
                return false;
            }

            if (op == add)
            {
                retv = acl_add_perm(perms, perm);
            }
            else
            {
                retv = acl_delete_perm(perms, perm);
            }

            if (retv != 0)
            {
                Log(LOG_LEVEL_ERR, "Could not change ACE permission. (acl_[add|delete]_perms: %s)", GetErrorStr());
                return false;
            }
            mode++;
        }

        // parse native perms

        if (*mode == CF_NATIVE_PERMS_SEP_START)
        {
            mode++;

            while (*mode != '\0' && strchr(CF_VALID_NPERMS_POSIX, *mode))
            {
                switch (*mode)
                {
                case 'r':
                    perm = ACL_READ;
                    break;

                case 'w':
                    perm = ACL_WRITE;
                    break;

                case 'x':
                    perm = ACL_EXECUTE;
                    break;

                default:
                    Log(LOG_LEVEL_ERR, "No linux support for native permission flag '%c'", *mode);
                    return false;
                }

                if (op == add)
                {
                    retv = acl_add_perm(perms, perm);
                }
                else
                {
                    retv = acl_delete_perm(perms, perm);
                }

                if (retv != 0)
                {
                    Log(LOG_LEVEL_ERR, "Could not change ACE permission. (acl_[add|delete]_perm: %s)", GetErrorStr());
                    return false;
                }
                mode++;
            }

            // scan past native perms end seperator
            mode++;
        }

        if (*mode == ',')
        {
            more_entries = true;
            mode++;
        }
        else
        {
            more_entries = false;
        }
    }

    return true;
}
Esempio n. 14
0
/*
 * return an ACL corresponding to the permissions
 * contained in struct stat
 */
static acl_t
acl_from_stat(struct stat sb)
{
	acl_t acl;
	acl_entry_t entry;
	acl_permset_t perms;

	/* create the ACL */
	acl = acl_init(3);
	if (!acl)
		return NULL;

	/* First entry: ACL_USER_OBJ */
	if (acl_create_entry(&acl, &entry) == -1)
		return NULL;
	if (acl_set_tag_type(entry, ACL_USER_OBJ) == -1)
		return NULL;

	if (acl_get_permset(entry, &perms) == -1)
		return NULL;
	if (acl_clear_perms(perms) == -1)
		return NULL;

	/* calculate user mode */
	if (sb.st_mode & S_IRUSR)
		if (acl_add_perm(perms, ACL_READ) == -1)
			return NULL;
	if (sb.st_mode & S_IWUSR)
		if (acl_add_perm(perms, ACL_WRITE) == -1)
			return NULL;
	if (sb.st_mode & S_IXUSR)
		if (acl_add_perm(perms, ACL_EXECUTE) == -1)
			return NULL;
	if (acl_set_permset(entry, perms) == -1)
		return NULL;

	/* Second entry: ACL_GROUP_OBJ */
	if (acl_create_entry(&acl, &entry) == -1)
		return NULL;
	if (acl_set_tag_type(entry, ACL_GROUP_OBJ) == -1)
		return NULL;

	if (acl_get_permset(entry, &perms) == -1)
		return NULL;
	if (acl_clear_perms(perms) == -1)
		return NULL;

	/* calculate group mode */
	if (sb.st_mode & S_IRGRP)
		if (acl_add_perm(perms, ACL_READ) == -1)
			return NULL;
	if (sb.st_mode & S_IWGRP)
		if (acl_add_perm(perms, ACL_WRITE) == -1)
			return NULL;
	if (sb.st_mode & S_IXGRP)
		if (acl_add_perm(perms, ACL_EXECUTE) == -1)
			return NULL;
	if (acl_set_permset(entry, perms) == -1)
		return NULL;

	/* Third entry: ACL_OTHER */
	if (acl_create_entry(&acl, &entry) == -1)
		return NULL;
	if (acl_set_tag_type(entry, ACL_OTHER) == -1)
		return NULL;

	if (acl_get_permset(entry, &perms) == -1)
		return NULL;
	if (acl_clear_perms(perms) == -1)
		return NULL;

	/* calculate other mode */
	if (sb.st_mode & S_IROTH)
		if (acl_add_perm(perms, ACL_READ) == -1)
			return NULL;
	if (sb.st_mode & S_IWOTH)
		if (acl_add_perm(perms, ACL_WRITE) == -1)
			return NULL;
	if (sb.st_mode & S_IXOTH)
		if (acl_add_perm(perms, ACL_EXECUTE) == -1)
			return NULL;
	if (acl_set_permset(entry, perms) == -1)
		return NULL;

	return(acl);
}
Esempio n. 15
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);
}
Esempio 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);
}
Esempio 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;
}
Esempio n. 18
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;
}
Esempio n. 19
0
int
__oldacl_add_perm(acl_permset_t permset_d, oldacl_perm_t perm)
{

	return (acl_add_perm(permset_d, perm));
}
Esempio n. 20
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;
}
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);
}
Esempio n. 22
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);
}
Esempio n. 23
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;
}