306 lines
5.9 KiB
C
Executable File
306 lines
5.9 KiB
C
Executable File
#ifndef lint
|
|
static char sccsid[] = "@(#)getfacl.c 1.4 93/11/05 SMI";
|
|
#endif
|
|
|
|
/*
|
|
* Copyright (c) 1993, by Sun Microsystems, Inc.
|
|
*/
|
|
|
|
/*
|
|
* getfacl [-ad] file ...
|
|
* This command displays discretionary information for a file or files.
|
|
* display format:
|
|
* # file: filename
|
|
* # owner: uid
|
|
* # group: gid
|
|
* user::perm
|
|
* user:uid:perm
|
|
* group::perm
|
|
* group:gid:perm
|
|
* mask:perm
|
|
* other:perm
|
|
* default:user::perm
|
|
* default:user:uid:perm
|
|
* default:group::perm
|
|
* default:group:gid:perm
|
|
* default:mask:perm
|
|
* default:other:perm
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <pwd.h>
|
|
#include <grp.h>
|
|
#include <locale.h>
|
|
#include <sys/acl.h>
|
|
|
|
static char *pruname(uid_t);
|
|
static char *prgname(gid_t);
|
|
static char *display(int);
|
|
static void usage();
|
|
|
|
main(int argc, char *argv[])
|
|
{
|
|
int c;
|
|
int aflag = 0;
|
|
int dflag = 0;
|
|
int errflag = 0;
|
|
int savecnt;
|
|
int aclcnt;
|
|
int mask;
|
|
aclent_t *aclp;
|
|
aclent_t *tp;
|
|
char *permp;
|
|
|
|
(void) setlocale(LC_ALL, "");
|
|
(void) textdomain(TEXT_DOMAIN);
|
|
|
|
if (argc < 2)
|
|
usage();
|
|
|
|
while ((c = getopt(argc, argv, "ad")) != EOF) {
|
|
switch (c) {
|
|
case 'a':
|
|
aflag++;
|
|
break;
|
|
case 'd':
|
|
dflag++;
|
|
break;
|
|
case '?':
|
|
errflag++;
|
|
break;
|
|
}
|
|
}
|
|
if (errflag)
|
|
usage();
|
|
|
|
if (optind >= argc)
|
|
usage();
|
|
|
|
for (; optind < argc; optind++) {
|
|
register char *filep;
|
|
|
|
filep = argv[optind];
|
|
|
|
/* Get ACL info of the files */
|
|
if ((aclcnt = acl(filep, GETACLCNT, 0, NULL)) < 0) {
|
|
(void) fprintf(stderr,
|
|
gettext("%s: failed to get acl count\n"), filep);
|
|
exit(2);
|
|
}
|
|
if (aclcnt < MIN_ACL_ENTRIES) {
|
|
(void) fprintf(stderr,
|
|
gettext("%d: acl count too small from %s\n"),
|
|
aclcnt, filep);
|
|
exit(2);
|
|
}
|
|
|
|
if ((aclp = (aclent_t *)malloc(sizeof (aclent_t) * aclcnt))
|
|
== NULL) {
|
|
(void) fprintf(stderr,
|
|
gettext("Insufficient memory\n"));
|
|
exit(1);
|
|
}
|
|
if (acl(filep, GETACL, aclcnt, aclp) < 0) {
|
|
(void) fprintf(stderr,
|
|
gettext("%s: failed to get acl entries\n"), filep);
|
|
exit(2);
|
|
}
|
|
|
|
/* display ACL: assume it is sorted. */
|
|
(void) printf("\n# file: %s\n", filep);
|
|
savecnt = aclcnt;
|
|
for (tp = aclp; aclcnt--; tp++) {
|
|
if (tp->a_type == USER_OBJ)
|
|
(void) printf("# owner: %s\n",
|
|
pruname(tp->a_id));
|
|
if (tp->a_type == GROUP_OBJ)
|
|
(void) printf("# group: %s\n",
|
|
prgname(tp->a_id));
|
|
if (tp->a_type == CLASS_OBJ)
|
|
mask = tp->a_perm;
|
|
}
|
|
aclcnt = savecnt;
|
|
for (tp = aclp; aclcnt--; tp++) {
|
|
switch (tp->a_type) {
|
|
case USER:
|
|
if (!dflag) {
|
|
permp = display(tp->a_perm);
|
|
(void) printf("user:%s:%s\t\t",
|
|
pruname(tp->a_id), permp);
|
|
free(permp);
|
|
permp = display(tp->a_perm & mask);
|
|
(void) printf(
|
|
"#effective:%s\n", permp);
|
|
free(permp);
|
|
}
|
|
break;
|
|
case USER_OBJ:
|
|
if (!dflag) {
|
|
/* no need to display uid */
|
|
permp = display(tp->a_perm);
|
|
(void) printf("user::%s\n", permp);
|
|
free(permp);
|
|
}
|
|
break;
|
|
case GROUP:
|
|
if (!dflag) {
|
|
permp = display(tp->a_perm);
|
|
(void) printf("group:%s:%s\t\t",
|
|
prgname(tp->a_id), permp);
|
|
free(permp);
|
|
permp = display(tp->a_perm & mask);
|
|
(void) printf(
|
|
"#effective:%s\n", permp);
|
|
free(permp);
|
|
}
|
|
break;
|
|
case GROUP_OBJ:
|
|
if (!dflag) {
|
|
permp = display(tp->a_perm);
|
|
(void) printf("group::%s\t\t", permp);
|
|
free(permp);
|
|
permp = display(tp->a_perm & mask);
|
|
(void) printf(
|
|
"#effective:%s\n", permp);
|
|
free(permp);
|
|
}
|
|
break;
|
|
case CLASS_OBJ:
|
|
if (!dflag) {
|
|
permp = display(tp->a_perm);
|
|
(void) printf("mask:%s\n", permp);
|
|
free(permp);
|
|
}
|
|
break;
|
|
case OTHER_OBJ:
|
|
if (!dflag) {
|
|
permp = display(tp->a_perm);
|
|
(void) printf("other:%s\n", permp);
|
|
free(permp);
|
|
}
|
|
break;
|
|
case DEF_USER:
|
|
if (!aflag) {
|
|
permp = display(tp->a_perm);
|
|
(void) printf("default:user:%s:%s\n",
|
|
pruname(tp->a_id), permp);
|
|
free(permp);
|
|
}
|
|
break;
|
|
case DEF_USER_OBJ:
|
|
if (!aflag) {
|
|
permp = display(tp->a_perm);
|
|
(void) printf("default:user::%s\n",
|
|
permp);
|
|
free(permp);
|
|
}
|
|
break;
|
|
case DEF_GROUP:
|
|
if (!aflag) {
|
|
permp = display(tp->a_perm);
|
|
(void) printf("default:group:%s:%s\n",
|
|
prgname(tp->a_id), permp);
|
|
free(permp);
|
|
}
|
|
break;
|
|
case DEF_GROUP_OBJ:
|
|
if (!aflag) {
|
|
permp = display(tp->a_perm);
|
|
(void) printf("default:group::%s\n",
|
|
permp);
|
|
free(permp);
|
|
}
|
|
break;
|
|
case DEF_CLASS_OBJ:
|
|
if (!aflag) {
|
|
permp = display(tp->a_perm);
|
|
(void) printf("default:mask:%s\n",
|
|
permp);
|
|
free(permp);
|
|
}
|
|
break;
|
|
case DEF_OTHER_OBJ:
|
|
if (!aflag) {
|
|
permp = display(tp->a_perm);
|
|
(void) printf("default:other:%s\n",
|
|
permp);
|
|
free(permp);
|
|
}
|
|
break;
|
|
default:
|
|
(void) fprintf(stderr,
|
|
gettext("unrecognized entry\n"));
|
|
break;
|
|
}
|
|
}
|
|
free(aclp);
|
|
}
|
|
exit(0);
|
|
}
|
|
|
|
static char *
|
|
display(int perm)
|
|
{
|
|
char *buf;
|
|
|
|
buf = malloc(4);
|
|
if (buf == NULL) {
|
|
(void) fprintf(stderr, gettext("Insufficient memory\n"));
|
|
exit(1);
|
|
}
|
|
|
|
if (perm & 4)
|
|
buf[0] = 'r';
|
|
else
|
|
buf[0] = '-';
|
|
if (perm & 2)
|
|
buf[1] = 'w';
|
|
else
|
|
buf[1] = '-';
|
|
if (perm & 1)
|
|
buf[2] = 'x';
|
|
else
|
|
buf[2] = '-';
|
|
buf[3] = '\0';
|
|
return (buf);
|
|
}
|
|
|
|
static char *
|
|
pruname(uid_t uid)
|
|
{
|
|
struct passwd *passwdp;
|
|
static char uidp[10]; /* big enough */
|
|
|
|
passwdp = getpwuid(uid);
|
|
if (passwdp == (struct passwd *) NULL) {
|
|
/* could not get passwd information: display uid instead */
|
|
sprintf(uidp, "%d", uid);
|
|
return (uidp);
|
|
} else
|
|
return (passwdp->pw_name);
|
|
}
|
|
|
|
static char *
|
|
prgname(gid_t gid)
|
|
{
|
|
struct group *groupp;
|
|
static char gidp[10]; /* big enough */
|
|
|
|
groupp = getgrgid(gid);
|
|
if (groupp == (struct group *) NULL) {
|
|
/* could not get group information: display gid instead */
|
|
sprintf(gidp, "%d", gid);
|
|
return (gidp);
|
|
} else
|
|
return (groupp->gr_name);
|
|
}
|
|
|
|
static void
|
|
usage()
|
|
{
|
|
(void) fprintf(stderr,
|
|
gettext("usage: getfacl [-ad] file ... \n"));
|
|
exit(1);
|
|
}
|