ppriv.c revision 2a12f85ad140e332791b4bad1208a734c3f26bf3
/*
* 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
* 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 (c) 2013 by Delphix. All rights reserved.
*/
/*
* Program to examine or set process privileges.
*/
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <limits.h>
#include <libproc.h>
#include <priv.h>
#include <errno.h>
#include <ctype.h>
#include <locale.h>
#include <langinfo.h>
static int look(char *);
static void perr(char *);
static void usage(void);
static void loadprivinfo(void);
static int parsespec(const char *);
static void privupdate(prpriv_t *, const char *);
static void privupdate_self(void);
static int dumppriv(char **);
static char *command;
static char *procname;
static int mode = PRIV_STR_PORT;
int
{
int rc = 0;
int opt;
(void) textdomain(TEXT_DOMAIN);
command++;
else
switch (opt) {
case 'l':
break;
case 'D':
break;
case 'M':
break;
case 'N':
break;
case 'P':
break;
case 'e':
break;
case 'S':
break;
case 'v':
mode = PRIV_STR_LIT;
break;
case 's':
return (rc);
break;
case 'x':
break;
default:
usage();
/*NOTREACHED*/
}
}
usage();
/*
* Make sure we'll have enough file descriptors to handle a target
* that has many many mappings.
*/
}
if (exec) {
} else if (list) {
} else {
while (argc-- > 0)
}
return (rc);
}
static int
{
struct ps_prochandle *Pr;
int gcode;
void *pdata;
char *x;
int i;
return (1);
}
return (1);
}
/*
* The ppriv fields are unsigned and may overflow, so check them
* separately. Size must be word aligned, so check that too.
* Make sure size is "smallish" too.
*/
"%s: %s: bad PRNOTES section, size = %lx\n",
return (1);
}
if (set) {
return (1);
}
return (0);
}
(void) printf("core '%s' of %d:\t%.70s\n",
} else {
(void) printf("%d:\t%.70s\n",
}
/* LINTED: alignment */
switch (pi->priv_info_type) {
case PRIV_INFO_FLAGS:
/* LINTED: alignment */
pii = (priv_info_uint_t *)x;
(void) printf("flags =");
(void) putchar('\n');
break;
default:
break;
}
break;
}
x += pi->priv_info_size;
}
extern const char *__priv_getsetbynum(const void *, int);
priv_getsetbynum(i);
priv_chunk_t *pc =
if (!nodata) {
extern char *__priv_set_to_str(void *,
const priv_set_t *, char, int);
char *s;
if (pdata)
else
(void) puts(s);
free(s);
} else {
int j;
for (j = 0; j < ppriv->pr_setsize; j++)
(void) putchar('\n');
}
}
return (0);
}
static void
fatal(const char *s)
{
exit(3);
}
static void
perr(char *s)
{
if (s != NULL)
else
s = procname;
perror(s);
}
static void
usage(void)
{
"usage:\t%s [-v] [-S] [-D|-N] [-s spec] { pid | core } ...\n"
"\t%s -e [-D|-N] [-M] [-s spec] cmd [args ...]\n"
"\t%s -l [-v] [privilege ...]\n"
" (report, set or list process privileges)\n", command,
exit(2);
/*NOTREACHED*/
}
/*
* a privilege set.
*
* [EPIL][+-=]priv,priv,priv
*/
static int
{
const char *s;
if (islower(c))
c = toupper(c);
if (s == NULL)
return (-1);
else
return (s - str);
}
static void
{
exit(3);
/*NOTREACHED*/
}
/*
* remove or you can set assign.
*/
static char *sets;
static void
loadprivinfo(void)
{
int i;
return;
pri = getprivimplinfo();
fatal("getprivimplinfo");
fatal("malloc");
for (i = 0; i < pri->priv_nsets; i++) {
sets[i] = *priv_getsetbynum(i);
}
fatal("calloc");
}
static int
{
char *p;
const char *q;
int count;
priv_set_t ***toupd;
int i;
loadprivinfo();
badspec(p + 1);
switch (*p) {
case '+':
break;
case '-':
break;
case '=':
break;
}
/* Update all sets? */
q = sets;
} else
q = spec;
for (i = 0; i < count; i++) {
if (ind == -1)
exit(1);
}
if (*p == '-')
else
} else {
}
}
if (freeupd)
return (0);
}
static void
{
int i;
for (i = 0; i < pri->priv_nsets; i++) {
priv_set_t *target =
}
}
/* LINTED: alignment */
/* LINTED: alignment */
pii = (priv_info_uint_t *)x;
goto done;
}
break;
x += pi->priv_info_size;
}
"%s: cannot find privilege flags to set\n", arg);
pr->pr_infosize = 0;
return;
done:
/* LINTED: alignment */
pii = (priv_info_uint_t *)
if (Don)
fl |= PRIV_DEBUG;
if (Doff)
fl &= ~PRIV_DEBUG;
if (pfexec)
fl |= PRIV_PFEXEC;
if (xpol)
fl |= PRIV_XPOLICY;
} else {
pr->pr_infosize = 0;
}
}
static void
privupdate_self(void)
{
int set;
if (mac_aware) {
fatal("setpflags(NET_MAC_AWARE)");
fatal("setpflags(NET_MAC_AWARE_INHERIT)");
}
if (pfexec) {
fatal("setpflags(PRIV_PFEXEC)");
}
fatal("priv_allocet");
fatal("setppriv(Inheritable)");
}
fatal("setppriv(Limit)");
}
}
if (xpol)
if (pfexec)
}
static int
dopriv(const char *p)
{
(void) puts(p);
if (verb) {
char *text = priv_gettext(p);
char *p, *q;
return (1);
*q = '\0';
(void) printf("\t%s\n", p);
}
}
return (0);
}
static int
{
int rc = 0;
const char *pname;
int i;
} else {
rc++;
continue;
}
}
}
return (rc);
}
static struct {
int flag;
char *name;
} flags[] = {
{ PRIV_DEBUG, "PRIV_DEBUG" },
{ PRIV_AWARE, "PRIV_AWARE" },
{ PRIV_AWARE_INHERIT, "PRIV_AWARE_INHERIT" },
{ PRIV_AWARE_RESET, "PRIV_AWARE_RESET" },
{ PRIV_XPOLICY, "PRIV_XPOLICY" },
{ PRIV_PFEXEC, "PRIV_PFEXEC" },
{ NET_MAC_AWARE, "NET_MAC_AWARE" },
{ NET_MAC_AWARE_INHERIT, "NET_MAC_AWARE_INHERIT" },
};
/*
* Print flags preceeded by a space.
*/
static void
{
char c = ' ';
int i;
if (pflags == 0) {
return;
}
c = '|';
}
}
if (pflags != 0)
}