OpenSolaris_b135/cmd/getfacl/getfacl.c

Compare this file to the similar file:
Show the results in this format:

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#ifndef lint
static char sccsid[] = "%Z%%M%	%I%	%E% SMI";
#endif

/*
 * 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>
#include <errno.h>

static char	*pruname(uid_t);
static char	*prgname(gid_t);
static char	*display(int);
static void	usage();


int
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 */
		errno = 0;
		if ((aclcnt = acl(filep, GETACLCNT, 0, NULL)) < 0) {
			if (errno == ENOSYS) {
				(void) fprintf(stderr,
				    gettext("File system doesn't support "
				    "aclent_t style ACL's.\n"
				    "See acl(5) for more information on "
				    "Solaris ACL support.\n"));
				exit(2);
			}
			perror(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);
		}

		errno = 0;
		if (acl(filep, GETACL, aclcnt, aclp) < 0) {
			perror(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);
	}
	return (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 */
		(void) sprintf(uidp, "%u", 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 */
		(void) sprintf(gidp, "%u", gid);
		return (gidp);
	} else
		return (groupp->gr_name);
}

static void
usage()
{
	(void) fprintf(stderr,
	    gettext("usage: getfacl [-ad] file ... \n"));
	exit(1);
}