allocate3.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 1999-2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <auth_attr.h>
#include <auth_list.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <libintl.h>
#include <locale.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <bsm/audit_uevents.h>
#include <sys/resource.h>
#include "allocate.h"
#ifdef DEBUG
#else /* !DEBUG */
#define dprintf(s, a)
#define dperror(s)
#endif /* DEBUG */
else \
return (number); \
}
#define DEVICE_AUTH_SEPARATOR ","
#define PROCFS "/proc/"
extern void audit_allocate_list(char *);
extern void audit_allocate_device(char *);
extern char *newenv[];
/*
* Checks if the specified user has any of the authorizations in the
* list of authorizations
*/
static int
{
char *auth;
return (0);
}
return (1);
}
return (0);
}
static int
check_devs(char *list)
{
char *file;
return (-1);
}
}
return (0);
}
static void
{
char *file;
}
(void) printf("\n");
}
static int
{
char file_name[MAXPATHLEN];
char *list;
int bytes_formated;
dprintf("Unable to find %s in the allocate database\n",
device);
return (NODMAPENT);
NULL) {
dprintf("Unable to find %s in the allocate database\n",
device);
return (NODAENT);
}
return (NODMAPENT);
}
if (bytes_formated <= 0) {
return (DEVNAME_ERR);
} else if (bytes_formated >= MAXPATHLEN) {
return (DEVNAME_TOOLONG);
}
dperror("Error:");
return (DACACC);
}
return (ALLOC);
return (ALLOC_OTHER);
return (NALLOC);
return (ALLOCERR);
return (SYSERROR);
return (DSPMISS);
}
return (0);
}
int
{
return (NOTAUTH);
}
setdaent();
if (device) {
}
dperror("Can't open DAC_DIR");
return (DACACC);
}
continue;
} else {
}
}
enddaent();
return (ret_code);
}
/*
* Set the DAC characteristics of the file.
* This uses a fancy chmod() by setting a minimal ACL which sets the mode
* and discards any existing ACL.
*/
static int
{
int err = 0;
do {
dperror("newdac, unable to chown");
err = CHOWN_PERR;
}
dperror("newdac, unable to setacl");
err = SETACL_PERR;
}
return (err);
}
static int
{
int fd;
dperror("lock_dev, cannot open DAC file");
return (DACACC);
}
dperror("lock_dev, cannot set lock");
return (DACLCK);
}
return (0);
}
static int
{
char *file;
int err;
return (err);
}
}
return (0);
}
/*
* working with the file, even "vold" (bug #4095152).
*/
static int
{
char buf[MAXPATHLEN];
/*
* vfork() and execle() just to make the same output
* as before fixing of bug #4095152.
* The problem is that the "fuser" command prints
* one part of output into stderr and another into stdout,
* but user sees them mixed. Of course, better to change "fuser"
* or to intercept and not to print its output.
*/
if (c_pid == -1)
return (-1);
if (c_pid == 0) {
newenv);
dperror("first exec fuser");
_exit(1);
}
if (WEXITSTATUS(lock) != 0)
return (-1);
}
if (pipe(p)) {
dperror("pipe");
return (-1);
}
/* vfork() and execle() to catch output and to process it */
if (c_pid == -1) {
dperror("second vfork");
return (-1);
}
if (c_pid == 0) {
(void) close(p[0]);
(void) close(1);
(void) close(p[1]);
(void) close(2);
dperror("second exec fuser");
_exit(1);
}
(void) close(p[1]);
continue;
}
== -1) {
dperror("");
continue;
}
continue;
}
dperror("");
break;
}
}
}
} else {
dperror("fdopen(p[0])");
r = -1;
}
return (r);
}
static int
{
char *file;
int error = 0;
switch (child) {
case -1:
return (-1);
case 0:
(void) setuid(0);
dprintf("mk_unalloc: unable to revoke %s\n",
file);
dperror("");
break;
}
}
default:
return (WEXITSTATUS(status));
}
return (-1);
}
}
static int
{
int status;
int c;
mode = "-I";
mode = "-i";
mode = "-f";
else
mode = "-s";
else
cmd++; /* skip leading '/' */
c = vfork();
switch (c) {
case -1:
return (-1);
case 0:
(void) setuid(0);
dperror("");
default:
return (WEXITSTATUS(status));
return (-1);
}
}
static int
{
char file_name[MAXPATHLEN];
char *list;
int bytes_formated;
if (bytes_formated <= 0) {
return (DEVNAME_ERR);
} else if (bytes_formated >= MAXPATHLEN) {
return (DEVNAME_TOOLONG);
}
dperror("Error:");
return (DACACC);
}
return (NALLOCU);
}
return (ALLOCERR);
} else
return (NALLOC);
}
/* All checks passed, time to lock and deallocate */
return (error);
!= 0) {
}
dprintf("Unable to find %s in the device map database\n",
} else {
} else {
}
}
}
return (error);
}
static int
{
char file_name[MAXPATHLEN];
char *list;
int error = 0;
int bytes_formated;
if (bytes_formated <= 0) {
return (DEVNAME_ERR);
} else if (bytes_formated >= MAXPATHLEN) {
return (DEVNAME_TOOLONG);
}
dperror("Error:");
return (DACACC);
}
if (DEV_ALLOCATED(stat_buf)) {
dprintf("Couldn't force deallocate device %s\n",
return (CNTFRC);
}
return (ALLOC);
} else
return (ALLOC_OTHER);
}
return (ALLOCERR);
return (AUTHERR);
}
dprintf("User %d is unauthorized to allocate\n",
(int)uid);
return (IMPORT_ERR);
}
}
dprintf("Unable to find %s in device map database\n",
return (NODMAPENT);
}
return (SYSERROR);
return (DSPMISS);
}
/* All checks passed, time to lock and allocate */
return (error);
}
return (error);
}
/* refresh list from check_devs overwritting it */
/* refresh list from mk_alloc overwritting it */
return (DEVLST);
}
return (0);
}
int
{
return (NOTAUTH);
setdaent();
setdmapent();
return (NODMAPENT);
== NULL)
return (NODAENT);
}
}
return (0);
}
}
enddaent();
return (NO_DEVICE);
}
int
{
return (NOTAUTH);
setdaent();
setdmapent();
return (NODMAPENT);
== NULL)
return (NODAENT);
}
}
dperror("Can't open DAC_DIR");
return (DACACC);
}
continue;
} else {
continue;
}
}
}
enddaent();
return (error);
}