From: Simone Piccardi Date: Sat, 18 Mar 2006 23:56:38 +0000 (+0000) Subject: Programma di esempio delle funzioni delle capabilities, e un po' di X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=commitdiff_plain;h=2fcfdcb7ec5f5fdacbdeaff72961f1c35d0858dd;p=gapil.git Programma di esempio delle funzioni delle capabilities, e un po' di documentazione sulle funzioni di lettura. --- diff --git a/prochand.tex b/prochand.tex index 77fde66..4af6ea9 100644 --- a/prochand.tex +++ b/prochand.tex @@ -2219,22 +2219,21 @@ una libreria a parte,\footnote{la libreria programma le utilizza si dovrà indicare esplicitamente l'uso della suddetta libreria attraverso l'opzione \texttt{-lcap} del compilatore. -Le funzioni dell'interfaccia POSIX.1e prevedono l'uso di uno tipo di dato -opaco, \type{cap\_t}, come puntatore ai dati mantenuti nel cosiddetto -\textit{capability state},\footnote{si tratta in sostanza di un puntatore ad - una struttura interna utilizzata dalle librerie, i cui campi non devono mai - essere acceduti direttamente.} in sono memorizzati tutti i dati delle -\textit{capabilities}. In questo modo è possibile mascherare i dettagli della -gestione di basso livello, che potranno essere modificati senza dover cambiare -le funzioni dell'interfaccia, che faranno riferimento soltanto ad oggetti di -questo tipo. L'interfaccia pertanto non soltanto fornirà le funzioni per -modificare e leggere le \textit{capabilities}, ma anche quelle per gestire i -dati attraverso \type{cap\_t}. - -La prima funzione dell'interfaccia è allora quella che permette di -inizializzare un \textit{capability state}, allocando al contempo la memoria -necessaria per i relativi dati. La funzione è \funcd{cap\_init} ed il suo -prototipo è: +Le funzioni dell'interfaccia delle bozze di POSIX.1e prevedono l'uso di uno +tipo di dato opaco, \type{cap\_t}, come puntatore ai dati mantenuti nel +cosiddetto \textit{capability state},\footnote{si tratta in sostanza di un + puntatore ad una struttura interna utilizzata dalle librerie, i cui campi + non devono mai essere acceduti direttamente.} in sono memorizzati tutti i +dati delle \textit{capabilities}. In questo modo è possibile mascherare i +dettagli della gestione di basso livello, che potranno essere modificati senza +dover cambiare le funzioni dell'interfaccia, che faranno riferimento soltanto +ad oggetti di questo tipo. L'interfaccia pertanto non soltanto fornisce le +funzioni per modificare e leggere le \textit{capabilities}, ma anche quelle +per gestire i dati attraverso \type{cap\_t}. + +La prima funzione dell'interfaccia è quella che permette di inizializzare un +\textit{capability state}, allocando al contempo la memoria necessaria per i +relativi dati. La funzione è \funcd{cap\_init} ed il suo prototipo è: \begin{functions} \headdecl{sys/capability.h} @@ -2244,7 +2243,7 @@ prototipo \bodydesc{La funzione ritorna un valore non nullo in caso di successo e \macro{NULL} in caso di errore, nel qual caso \var{errno} assumerà il valore \errval{ENOMEM}. -} + } \end{functions} La funzione restituisce il puntatore \type{cap\_t} ad uno stato inizializzato @@ -2262,7 +2261,7 @@ funzione \funcd{cap\_free}, il cui prototipo \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di errore, nel qual caso \var{errno} assumerà il valore \errval{EINVAL}. -} + } \end{functions} La funzione permette di liberare la memoria allocata dalle altre funzioni @@ -2285,15 +2284,15 @@ precedenza tramite la funzione \funcd{cap\_dup}, il cui prototipo \bodydesc{La funzione ritorna un valore non nullo in caso di successo e \macro{NULL} in caso di errore, nel qual caso \var{errno} potrà assumere i valori \errval{ENOMEM} o \errval{EINVAL}. -} + } \end{functions} -La funzione crea una copia del \textit{capability state} \param{cap\_p} -passato come argomento, restituendo il puntatore alla copia che conterrà gli -stessi valori delle \textit{capabilities} presenti nell'originale. La memoria -necessaria viene allocata automaticamente dalla funzione. Una volta effettuata -la copia i due \textit{capability state} potranno essere modificati in maniera -completamente indipendente. +La funzione crea una copia del \textit{capability state} posto all'indirizzo +\param{cap\_p} che si è passato come argomento, restituendo il puntatore alla +copia, che conterrà gli stessi valori delle \textit{capabilities} presenti +nell'originale. La memoria necessaria viene allocata automaticamente dalla +funzione. Una volta effettuata la copia i due \textit{capability state} +potranno essere modificati in maniera completamente indipendente. Una seconda classe di funzioni di servizio sono quelle per la gestione dei dati contenuti all'interno di un \textit{capability state}; la prima di esse è @@ -2307,13 +2306,13 @@ dati contenuti all'interno di un \textit{capability state}; la prima di esse \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di errore, nel qual caso \var{errno} assumerà il valore \errval{EINVAL}. -} + } \end{functions} La funzione si limita ad azzerare tutte le \textit{capabilities} presenti nel -\textit{capability state} \param{cap\_p} passato come argomento restituendo -uno stato \textsl{vuoto}, analogo a quello che si ottiene nella creazione con -\func{cap\_init}. +\textit{capability state} all'indirizzo \param{cap\_p} passato come argomento, +restituendo uno stato \textsl{vuoto}, analogo a quello che si ottiene nella +creazione con \func{cap\_init}. Per la gestione dei valori delle \textit{capabilities} presenti in un \textit{capability state} l'interfaccia prevede due funzioni, @@ -2336,11 +2335,11 @@ rispettivamente di leggere o impostare il valore di un flag delle } \end{functions} -In entrambe le funzioni l'argomento \param{cap\_p} indica il +In entrambe le funzioni l'argomento \param{cap\_p} indica il puntatore al \textit{capability state} su cui operare, mentre l'argomento \param{flag} indica su quale dei tre insiemi illustrati a -pag.~\pageref{sec:capabilities_set} si intende operare. Questo deve essere -specificato con una variabile di tipo \type{cap\_flag\_t} e può assumere +pag.~\pageref{sec:capabilities_set} si intende operare. Questi devono essere +specificati con una variabile di tipo \type{cap\_flag\_t} che può assumere esclusivamente\footnote{si tratta in effetti di un tipo enumerato, come si può verificare dalla sua definizione che si trova in \texttt{/usr/include/sys/capability.h}.} uno dei valori illustrati in @@ -2364,18 +2363,18 @@ tab.~\ref{tab:cap_set_identifier}. \label{tab:cap_set_identifier} \end{table} -La capacità che si intende controllare o impostare deve essere specificata -attraverso una variabile di tipo \type{cap\_value\_t}, che può prendere come -valore uno qualunque di quelli riportati in tab.~\ref{tab:proc_capabilities}, -in questo caso però non è possibile combinare diversi valori in una maschera -binaria, una variabile di tipo \type{cap\_value\_t} deve indicare una sola -\textit{capabilities}.\footnote{nel file di header citato nella nota - precedente il tipo \type{cap\_value\_t} è definito come \ctyp{int}, ma i - valori validi sono soltanto quelli di tab.~\ref{tab:proc_capabilities}.} -Infine lo stato di una \textit{capabilities} è descritto ad una variabile di -tipo \type{cap\_flag\_value\_t}, che a sua volta può assumere soltanto -uno\footnote{anche questo è un tipo enumerato.} dei valori di -tab.~\ref{tab:cap_value_type}. +La capacità che si intende controllare o impostare invece deve essere +specificata attraverso una variabile di tipo \type{cap\_value\_t}, che può +prendere come valore uno qualunque di quelli riportati in +tab.~\ref{tab:proc_capabilities}, in questo caso però non è possibile +combinare diversi valori in una maschera binaria, una variabile di tipo +\type{cap\_value\_t} deve indicare una sola capacità.\footnote{nel file di + header citato nella nota precedente il tipo \type{cap\_value\_t} è definito + come \ctyp{int}, ma i valori validi sono soltanto quelli di + tab.~\ref{tab:proc_capabilities}.} Infine lo stato di una capacità è +descritto ad una variabile di tipo \type{cap\_flag\_value\_t}, che a sua volta +può assumere soltanto uno\footnote{anche questo è un tipo enumerato.} dei +valori di tab.~\ref{tab:cap_value_type}. \begin{table}[htb] \centering @@ -2398,7 +2397,7 @@ La funzione \func{cap\_get\_flag} legge lo stato della capacit dall'argomento \param{cap} all'interno dell'insieme indicato dall'argomento \param{flag} e ne restituisce il valore nella variabile posta all'indirizzo puntato dall'argomento \param{value\_p}; è possibile cioè leggere soltanto uno -stato di una \textit{capability} alla volta. +stato di una capacità alla volta. La funzione \func{cap\_set\_flag} può invece impostare in una sola chiamata più capacità, anche se solo all'interno dello stesso insieme; per questo essa @@ -2407,7 +2406,48 @@ prende un vettore di valori di tipo \type{cap\_value\_t} nell'argomento tipo di impostazione da eseguire (cancellazione o impostazione) viene indicato dall'argomento \param{value}. +Fin quei abbiamo trattato delle funzioni di manipolazione dei +\textit{capabilities state}; quando si vuole eseguire la lettura delle +\textit{capabilities} del processo corrente si deve usare la funzione +\funcd{cap\_get\_proc}, il cui prototipo è: +\begin{functions} + \headdecl{sys/capability.h} + + \funcdecl{cap\_t cap\_get\_proc(void)} + Legge le \textit{capabilities} del processo corrente. + + \bodydesc{La funzione ritorna un valore diverso da \val{NULL} in caso di + successo e \val{NULL} in caso di errore, nel qual caso \var{errno} può + assumere i valori \errval{EINVAL}, \errval{EPERM} o \errval{ENOMEM}. } +\end{functions} + +La funzione legge il valore delle \textit{capabilities} del processo corrente +e restituisce il puntatore ad un \textit{capabilities state} contenente il +risultato, che provvede ad allocare autonomamente, e che occorrerà liberare +con \func{cap\_free} quando non sarà più utilizzato. + +Se invece si vogliono leggere le \textit{capabilities} di un processo +specifico occorre usare la funzione \funcd{capgetp}, il cui +prototipo\footnote{su alcune pagine di manuale la funzione è descritta con un + prototipo sbagliato, che prevede un valore di ritorno di tipo \type{cap\_t}, + ma il valore di ritorno è intero, come si può verificare anche dalla + dichiarazione della stessa in \texttt{sys/capability.h}.} è: +\begin{functions} + \headdecl{sys/capability.h} + + \funcdecl{int capgetp(pid\_t pid, cap\_t cap\_d)} + Legge le \textit{capabilities} del processo indicato da \param{pid}. + + \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di + errore, nel qual caso \var{errno} può assumere i valori \errval{EINVAL}, + \errval{EPERM} o \errval{ENOMEM}. + } +\end{functions} +La funzione legge il valore delle \textit{capabilities} del processo indicato +con l'argomento \param{pid}, salvando il risultato nel \textit{capabilities + state} all'indirizzo \param{cap\_d} che deve essere stato creato in +precedenza. Qualora il processo non esista si avrà un errore di \errval{}. diff --git a/sources/Makefile b/sources/Makefile index 3d20078..56cbff4 100644 --- a/sources/Makefile +++ b/sources/Makefile @@ -13,7 +13,7 @@ OBJ = FullRead.o FullWrite.o SigHand.o Mutex.o SharedMem.o LockFile.o \ FINAL = forktest errcode echo echod daytimed iterdaytimed daytime testfopen \ testren fortune fortuned mqfortune mqfortuned flock myls dirmonitor \ - readmon ipctestid writeshm #readshm + readmon ipctestid writeshm getcap #readshm $(LIB): $(OBJ) gcc -shared -lrt $^ -o $@ @@ -115,9 +115,8 @@ wwwd: wwwd.c acctctrl: AcctCtrl.c $(CC) $(CFLAGS) $^ -o $@ -printcap: - $(CC) $(CFLAGS) $^ -o $@ - +getcap: getcap.c + $(CC) $(CFLAGS) $^ -lcap -o $@ # Macro per la generazione della tarball dei sorgenti package: clean gapil_source.tgz diff --git a/sources/getcap.c b/sources/getcap.c new file mode 100644 index 0000000..116f3cb --- /dev/null +++ b/sources/getcap.c @@ -0,0 +1,128 @@ +/* getcap.c + * + * Copyright (C) 2006 Simone Piccardi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/**************************************************************** + * + * Program getcap.c: + * Program to test capabilities functions + * + * Author: Simone Piccardi + * Mar. 2006 + * + * Usage: getcap -h give all info's + * + * + ****************************************************************/ +/* + * Include needed headers + */ +#define _GNU_SOURCE +#include /* error definitions and routines */ +#include /* C standard library */ +#include /* unix standard library */ +#include /* standard I/O library */ +#include /* string functions */ +#include +#include + +/* Help printing routine */ +void usage(void); + +int main(int argc, char *argv[]) +{ +/* + * Variables definition + */ + int i; + pid_t pid = 0; + cap_t capab = NULL; + char *string; + int res; + + /* + * Input section: decode command line parameters + * Use getopt function + */ + opterr = 0; /* don't want writing to stderr */ + while ( (i = getopt(argc, argv, "hp:")) != -1) { + switch (i) { + /* + * Handling options + */ + case 'h': /* help option */ + printf("Wrong -h option use\n"); + usage(); + return -1; + break; + case 'p': /* specify pid */ + pid = strtol(optarg, NULL, 10); + break; + case '?': /* unrecognized options */ + printf("Unrecognized options -%c\n",optopt); + usage(); + default: /* should not reached */ + usage(); + } + } + /* *********************************************************** + * + * Options processing completed + * + * Main code beginning + * + * ***********************************************************/ + if ( (argc-optind) != 0) { + printf("From %d arguments, removed %d options\n", argc, optind); + usage(); + } + + if (!pid) { + capab = cap_get_proc(); + if (capab == NULL) { + perror("cannot get current process capabilities"); + return 1; + } + } else { + capab = cap_init(); + res = capgetp(pid, capab); + if (res) { + perror("cannot get process capabilities"); + return 1; + } + } + + string = cap_to_text(capab, NULL); + printf("Capability: %s\n", string); + + cap_free(capab); + return 0; +} +/* + * routine to print usage info and exit + */ +void usage(void) { + printf("Program getcap: print current process capabilities \n"); + printf("Usage:\n"); + printf(" getcap [-h] [-p pid] \n"); + printf(" -h print this help\n"); + printf(" -p PID print process PID capabilities\n"); + + exit(1); +} + +