Solaris-ACL
view release on metacpan or search on metacpan
record_error(0, "no group_obj key in hash");
return -1;
}
if(matched_val = hv_fetch(acl_hash, OTHER_OBJ_KEY, OTHER_OBJ_KEY_LENGTH, 0))
{
if(add_acl_ent(OTHER_OBJ | def, 0, SvIV(*matched_val),
acl_ents, &i, num_acl_ents))
return -1;
}
else
{
record_error(0, "no other_obj key in hash");
return -1;
}
if(mask)
{
if(add_acl_ent(CLASS_OBJ | def, 0, SvIV(*mask),
acl_ents, &i, num_acl_ents))
return -1;
}
if(user_hash)
if(add_acl_list(user_hash, USER | def, acl_ents, &i, num_acl_ents))
return -1;
if(group_hash)
if(add_acl_list(group_hash, GROUP | def, acl_ents, &i, num_acl_ents))
return -1;
return 0; /* all's well that ends well... */
}
#define PACKAGE_NAME "Solaris::ACL"
MODULE = Solaris::ACL PACKAGE = Solaris::ACL
# getfacl(filename)
# getfacl returns the acls of a file, Barring error, the return is
# ($acl[, $default_acl]), where $acl and $default_acl are each
# hashrefs to hashes with entries for:
# user - a hash ref to a hash of the form { uid => file perm mode ...}
# group - ditto for gids
# uperm - perms for the file owner
# gperm - perms for the file group
# operm - perms for other
# mask - the mask
# If there are no default acl entries, then no default_acl hash is returned.
# If there is an error, then the null list is returned, and $! is set
# to indicate the error. A more informative error message can be found
# in $Solaris::ACL::error.
void
getfacl(file_name)
SV * file_name;
PPCODE:
{
char *file_string; /* c-string version of file_name */
int file_string_length; /* need to pass a variable to SvPV */
HV *acl_hash, *default_acl_hash, *current_acl_hash;
HV *user_hash, *default_user_hash, **current_user_hash;
HV *group_hash, *default_group_hash, **current_group_hash;
SV **acl_list_hash;
int num_acl_ents;
aclent_t *acl_ents;
int i;
file_string = SvPV(file_name,file_string_length);
if( (num_acl_ents=acl(file_string, GETACLCNT, 0, NULL)) == -1 )
{
record_error(1, "acl(%s, GETACLCNT) failed: ", file_string);
XSRETURN(0);
}
if (New(0,acl_ents,num_acl_ents,aclent_t) == NULL)
{
record_error(1, "New(%, %d) failed: ",
num_acl_ents, sizeof(aclent_t));
XSRETURN(0);
}
if(acl(file_string, GETACL, num_acl_ents, acl_ents) == -1)
{
record_error(1, "acl(%s, GETACL) failed: ", file_string);
XSRETURN(0);
}
/* We have the acl. Now, convert it into our perl structure */
acl_hash = newHV();
default_acl_hash = NULL; /* until we see a default acl,
assume there is none */
user_hash = NULL; /* Until we see user acls, assume none */
group_hash = NULL; /* ditto */
default_user_hash = NULL; /* ditto */
default_group_hash = NULL; /* ditto */
for(i = 0; i < num_acl_ents; i++)
{
if (acl_ents[i].a_type & ACL_DEFAULT)
{
if(default_acl_hash == NULL)
default_acl_hash = newHV();
current_acl_hash = default_acl_hash;
current_user_hash = &default_user_hash;
current_group_hash = &default_group_hash;
}
else
{
current_acl_hash = acl_hash;
current_user_hash = &user_hash;
current_group_hash = &group_hash;
}
hv_store(current_acl_hash, OTHER_OBJ_KEY, OTHER_OBJ_KEY_LENGTH,
newSViv(acl_ents[i].a_perm), 0);
break;
case CLASS_OBJ: /* acl mask */
hv_store(current_acl_hash, MASK_OBJ_KEY, MASK_OBJ_KEY_LENGTH,
newSViv(acl_ents[i].a_perm), 0);
break;
case USER: /* additional users */
if (*current_user_hash == NULL) /* is this our first user acl? */
{
*current_user_hash = newHV();
hv_store(current_acl_hash, USER_KEY, USER_KEY_LENGTH,
newRV_noinc((SV*)(*current_user_hash)), 0);
}
hv_store_ent(*current_user_hash, sv_2mortal(newSViv(acl_ents[i].a_id)),
newSViv(acl_ents[i].a_perm), 0);
break;
case GROUP: /* additional groups */
if (*current_group_hash == NULL) /* is this our first group acl? */
{
*current_group_hash = newHV();
hv_store(current_acl_hash, GROUP_KEY, GROUP_KEY_LENGTH,
newRV_noinc((SV*)(*current_group_hash)), 0);
}
hv_store_ent(*current_group_hash, sv_2mortal(newSViv(acl_ents[i].a_id)),
newSViv(acl_ents[i].a_perm), 0);
break;
}
}
Safefree(acl_ents);
XPUSHs(sv_2mortal(sv_bless(newRV_noinc((SV*)acl_hash),
gv_stashpv(PACKAGE_NAME,0))));
if(default_acl_hash == NULL) /* were there default acls? */
XSRETURN(1);
else
{
XPUSHs(sv_2mortal(sv_bless(newRV_noinc((SV*)default_acl_hash),
gv_stashpv(PACKAGE_NAME,0))));
XSRETURN(2);
}
}
# setfacl(filename, acl_hashref [, default_acl_hashref])
# setfacl sets the acl (and optionally the default acl) for filename.
# acl (and optionally default_acl) should be a reference to a hash with
# the same structure as in getfacl. The return is TRUE on sucess and FALSE
# on failure. If a failure is indicated, the caller should check the
# string $Solaris::ACL::error for more information. If the error is a
# system error, the error will also be in $!.
void
setfacl(file_name, acl_hashref, ...)
SV *file_name;
SV *acl_hashref;
PPCODE:
{
char *file_string; /* c-string version of file_name */
int file_string_length; /* need to pass a variable to SvPV */
HV *acl_hash, *def_acl_hash;
HV *user_hash, *group_hash, *def_user_hash, *def_group_hash;
SV **mask, **def_mask;
aclent_t *acl_ents;
int num_acl_ents;
struct stat stat_buf;
int num_def_acl_ents = 0;
if (items > 3)
croak("Usage: Solaris::ACL::setfacl(file_name, acl [, default_acl])");
/* are we over dereferencing in this next line ??? */
if(!(num_acl_ents =
pretest_acl(acl_hashref, &acl_hash, &user_hash, &group_hash, &mask)))
XSRETURN_NO;
if (items == 3)
{
if(!(num_def_acl_ents =
pretest_acl(ST(2), &def_acl_hash, &def_user_hash,
&def_group_hash, &def_mask)))
XSRETURN_NO;
}
file_string = SvPV(file_name,file_string_length);
/* Although it is not documented as mattering, the a_id field of
user_obj and group_obj entries in an acl is set to be the actual
user or group id of the file, at least when the acl is modified
by setfacl(1) or chmod(1). In case something actually depends on
this, we are grabbing the user and group ids of the file via
stat. */
if(stat(file_string, &stat_buf))
{
record_error(1, "stat(%s) failed: ", file_string);
XSRETURN_NO;
}
if (New(0,acl_ents, num_acl_ents + num_def_acl_ents, aclent_t) == NULL)
{
record_error(1, "New(%d, %d) failed: ",
num_acl_ents + num_def_acl_ents, sizeof(aclent_t));
XSRETURN_NO;
}
if (populate_acl(acl_ents, 0, acl_hash, user_hash,
group_hash, mask, num_acl_ents,
stat_buf.st_uid, stat_buf.st_gid))
XSRETURN_NO;
if (items == 3)
if (populate_acl(&acl_ents[num_acl_ents], ACL_DEFAULT, def_acl_hash,
( run in 1.213 second using v1.01-cache-2.11-cpan-5511b514fd6 )