How to check if a UID exists in an ACL in Linux?
I need to write a program, part of which involves c开发者_JS百科hecking if the userid of the person executing the program exists in the ACL file of a file which the program uses. That is, this program writes into the file and only users whose ID and privileges are entered in the ACL are allowed to do so. How can the program check this? I know that I need to use the getresid
function to get the RUID of the executing process, but how do I check this value against all the values stored in the ACL? Please help me!
Traditionally, linux programs don't do interpretive access control very much. There are two cases.
Case 1, the simple case. A file has an acl (or just modes). Some user runs a program under his user/group set, and the kernel either allows or denies based on the modes/acl. All done.
Case 2, the hard case. A program runs as root, but wishes to operate on behalf of some other user. So, it calls setuid/setgid to 'become' that user, then performs the operation (like opening a file), and then calls to restore itself to root-itude afterwards.
However, based on your comments to chown's answer, I think that you are just in case 1. The user foo runs the program, so the kernel does all the work for you.
If I misunderstood the question I apologize, but hopefully you will find this helpful:
Exceprt from some acl documentation:
The following functions retrieve and manipulate ACL entries:
acl_copy_entry()
acl_create_entry()
acl_delete_entry()
acl_first_entry()
acl_get_entry()
The following functions retrieve and manipulate fields in an ACL entry:
acl_add_perm()
acl_clear_perm()
alc_delete_perm()
acl_get_permset()
acl_get_qualifier()
acl_get_tag_type()
acl_set_permset()
acl_set_qualifier()
acl_set_tag_type()
...
ACL Entries
An ACL entry consists of the following fields:
Tag type (defined in the acl.h header file):
ACL_USER_OBJ - The owning user entry.
ACL_GROUP_OBJ - The owning group entry.
ACL_USER - An entry for other users.
ACL_GROUP - An entry for other groups.
ACL_OTHER_OBJ - The entry for all users and groups that are not included in another entry.
Tag qualifier - The qualifier value for a ACL_USER entry is a user ID.
The qualifier value for a ACL_GROUP entry is a group ID. The qualifier value for any of the *_OBJ entries is NULL.
From acl_update.c:
/*
Find the the ACL entry in 'acl' corresponding to the tag type and
qualifier in 'tag' and 'id'. Return the matching entry, or NULL
if no entry was found. */
static acl_entry_t
findEntry(acl_t acl, acl_tag_t tag, id_t qaul)
{
acl_entry_t entry;
acl_tag_t entryTag;
uid_t *uidp;
gid_t *gidp;
int ent, s;
for (ent = ACL_FIRST_ENTRY; ; ent = ACL_NEXT_ENTRY) {
s = acl_get_entry(acl, ent, &entry);
if (s == -1)
errExit("acl_get_entry");
if (s == 0)
return NULL;
if (acl_get_tag_type(entry, &entryTag) == -1)
errExit("acl_get_tag_type");
if (tag == entryTag) {
if (tag == ACL_USER) {
uidp = acl_get_qualifier(entry);
if (uidp == NULL)
errExit("acl_get_qualifier");
if (qaul == *uidp) {
if (acl_free(uidp) == -1)
errExit("acl_free");
return entry;
} else {
if (acl_free(uidp) == -1)
errExit("acl_free");
}
} else if (tag == ACL_GROUP) {
gidp = acl_get_qualifier(entry);
if (gidp == NULL)
errExit("acl_get_qualifier");
if (qaul == *gidp) {
if (acl_free(gidp) == -1)
errExit("acl_free");
return entry;
} else {
if (acl_free(gidp) == -1)
errExit("acl_free");
}
} else {
return entry;
}
}
}
}
I dont think u need to check the ACL of a specific file, but if I am wrong, here is some info to do so:
$ getfacl myFile
# file: myFile
# owner: jon
# group: people
user::rwx
user:foo:rwx
group::rwx
mask::rwx
other::---
then to get a uid from the name (untested but should be close):
$ grep /etc/passwd `getfacl myFile | grep owner | split -d":" -f2` | egrep -o "[0-9]+"
Some more resources:
acl/facl examples and reference man acl
POSIX Access Control Lists
statacl
精彩评论