Programma di esempio delle funzioni delle capabilities, e un po' di
authorSimone Piccardi <piccardi@gnulinux.it>
Sat, 18 Mar 2006 23:56:38 +0000 (23:56 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sat, 18 Mar 2006 23:56:38 +0000 (23:56 +0000)
documentazione sulle funzioni di lettura.

prochand.tex
sources/Makefile
sources/getcap.c [new file with mode: 0644]

index 77fde66866240282070bde592145adfcec005bf4..4af6ea92cd27ba140ef19b19b6d417b2d7ea4e32 100644 (file)
@@ -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{}.
 
 
 
index 3d20078e6f3495af0a291cdce2080358836eb663..56cbff4b6cdf79fafa68b50fd1a936112b141e67 100644 (file)
@@ -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 (file)
index 0000000..116f3cb
--- /dev/null
@@ -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 <errno.h>       /* error definitions and routines */ 
+#include <stdlib.h>      /* C standard library */
+#include <unistd.h>      /* unix standard library */
+#include <stdio.h>      /* standard I/O library */
+#include <string.h>      /* string functions */
+#include <sys/types.h>
+#include <sys/capability.h>
+
+/* 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);
+}
+
+