/*
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* priv_str_xlate.c - Privilege translation routines.
*/
#include "lint.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <strings.h>
#include <errno.h>
#include <string.h>
#include <locale.h>
#include <priv.h>
#include <alloca.h>
#include <locale.h>
#include "libc.h"
#include "../i18n/_loc_path.h"
#include "priv_private.h"
priv_basic(void)
{
priv_data_t *d;
LOADPRIVDATA(d);
return (d->pd_basicset);
}
/*
* Name: priv_str_to_set()
*
* Description: Given a buffer with privilege strings, the
* equivalent privilege set is returned.
*
* Special tokens recognized: all, none, basic and "".
*
* On failure, this function returns NULL.
* *endptr == NULL and errno set: resource error.
* *endptr != NULL: parse error.
*/
const char *separators,
const char **endptr)
{
char *base;
char *offset;
char *last;
/* Whether base is NULL or allocated, this works */
return (NULL);
}
basic = priv_basic();
/* This is how to use strtok_r nicely in a while loop ... */
/*
* Search for these special case strings.
*/
} else {
int privid;
int slen;
if (privid < 0) {
return (NULL);
} else {
if (neg)
else
}
}
}
return (pset);
}
/*
* Name: priv_set_to_str()
*
* Description: Given a set of privileges, list of privileges are
* returned in privilege numeric order (which can be an ASCII sorted
* list as our implementation allows renumbering.
*
* String "none" identifies an empty privilege set, and string "all"
* identifies a full set.
*
* A pointer to a buffer is returned which needs to be freed by
* the caller.
*
* Several types of output are supported:
* PRIV_STR_PORT - portable output: basic,!basic
* PRIV_STR_LIT - literal output
* PRIV_STR_SHORT - shortest output
*
* NOTE: this function is called both from inside the library for the
* current environment and from outside the library using an externally
* generated priv_data_t * in order to analyze core files. It should
* return strings which can be free()ed by applications and it should
* not use any data from the current environment except in the special
* case that it is called from within libc, with a NULL priv_data_t *
* argument.
*/
char *
priv_data_t *d,
const priv_set_t *pset,
char separator,
int flag)
{
const char *pstr;
int i;
if (use_libc_data)
LOADPRIVDATA(d);
return (strdup("none"));
return (strdup("all"));
/* Safe upper bound: global info contains all NULL separated privs */
/*
* Compute the shortest form; i.e., the form with the fewest privilege
* tokens.
* The following forms are possible:
* literal: priv1,priv2,priv3
* tokcount = present
* port: basic,!missing_basic,other
* tokcount = 1 + present - presentbasic + missingbasic
* zone: zone,!missing_zone
* tokcount = 1 + missingzone
* all: all,!missing1,!missing2
* tokcount = 1 + d->pd_nprivs - present;
*
* Note that zone and all forms are identical in the global zone;
* in that case (or any other where the token count is the same),
* all is preferred. Also, the zone form is only used when the
* indicated privileges are a subset of the zone set.
*/
if (use_libc_data)
LOCKPRIVDATA();
if (flag == PRIV_STR_SHORT) {
int count;
presentzone = missingzone = 0;
zone = d->pd_zoneset;
for (i = 0; i < d->pd_nprivs; i++) {
if (d->pd_basicset != NULL &&
PRIV_ISMEMBER(d->pd_basicset, i)) {
if (mem)
presentbasic++;
else
missingbasic++;
}
if (mem)
presentzone++;
else
missingzone++;
}
if (mem)
present++;
}
} else {
flag = PRIV_STR_LIT;
}
}
}
}
switch (flag) {
case PRIV_STR_LIT:
*res = '\0';
break;
case PRIV_STR_PORT:
if (d->pd_basicset == NULL)
flag = PRIV_STR_LIT;
break;
case PRIV_STR_SHORT:
if (all)
else
break;
default:
if (use_libc_data)
return (NULL);
}
for (i = 0; i < d->pd_nprivs; i++) {
/* Map the privilege to the next one sorted by name */
switch (flag) {
case PRIV_STR_SHORT:
continue;
break;
case PRIV_STR_PORT:
continue;
break;
case PRIV_STR_LIT:
break;
}
} else {
switch (flag) {
case PRIV_STR_LIT:
continue;
case PRIV_STR_PORT:
continue;
break;
case PRIV_STR_SHORT:
continue;
break;
}
}
}
if (use_libc_data)
/* Special case the set with some high bits set */
}
/*
* priv_set_to_str() is defined to return a string that
* the caller must deallocate with free(3C). Grr...
*/
char *
{
}
static char *
{
return (NULL);
/*
* parse the file; it must have the following format
* Lines starting with comments "#"
* Lines starting with non white space with one single token:
* the privileges; white space indented lines which are the
* description; no empty lines are allowed in the description.
*/
if (buf[0] == '#')
continue;
if (buf[0] == '\n') {
continue;
}
if (inentry)
continue;
/* error; not skipping; yet line starts with white space */
goto out;
/* Trim trailing newline */
continue;
}
int len;
/* Empty line or start of next entry terminates */
*lp = '\0';
}
/* Remove leading white space */
while (*tstart != '\0' &&
tstart++;
}
/* Entry to big; prevent fgets() loop */
goto out;
}
*lp = '\0';
}
}
out:
return (NULL);
}
/*
* priv_gettext() is defined to return a string that
* the caller must deallocate with free(3C). Grr...
*/
char *
{
const char *loc;
char *ret;
/* Not a valid privilege */
if (priv_getbyname(priv) < 0)
return (NULL);
return (ret);
}
/* If the path is too long or can't be opened, punt to default */
return (ret);
}