#### Exemple C {-} \ Voici un exemple de code C utilisant `setns(2)` :
```c #define _GNU_SOURCE #include #include #include // ./a.out /proc/PID/ns/FILE cmd args... int main(int argc, char *argv[]) { int fd = open(argv[1], O_RDONLY); if (fd == -1) { perror("open"); return EXIT_FAILURE; } if (setns(fd, 0) == -1) { perror("setns"); return EXIT_FAILURE; } execvp(argv[2], &argv[2]); perror("execve"); return EXIT_FAILURE; } ```
Ce programme prend au minimum deux arguments : - le chemin d'un fichier d'espace de nom que l'on souhaite rejoindre (le chemin vers le lien symbolique donc) ; - le programme (et ses arguments) que l'on souhaite souhaite exécuter une fois que l'on a rejoint l'espace de noms ciblé. Dans un premier temps, on ouvre le fichier passé en paramètre afin d'obtenir un *file descriptor* de la structure du noyau. On passe ensuite ce *file descriptor* en argument de l'appel système `setns(2)`. Et enfin on exécute la commande données dans les derniers paramètres. ::::: {.question} #### Qu'attend le deuxième argument de `setns(2)` ? {-} \ Il s'agit d'une contrainte sur le type d'espace de nom que l'on souhaite rejoindre, dans le cas où on ne souhaite pas rejoindre n'importe quel espace de nom. Une fois encore, on utilisera les mêmes options `CLONE_NEW*` lorsque l'on attendra un type particulier d'espace de nom, ou 0 pour autoriser tous les types. ::::: ::::: {.question} #### Peut-on connaître le type de *namespace* à partir du *file descriptor* ? {-} \ Il est possible de récupérer le type d'espace de nom en passant notre *file descriptor* à `ioctl(2)`, avec le *flag* `NS_GET_NSTYPE` :
```c nstype = ioctl(fd, NS_GET_NSTYPE); if (nstype & CLONE_NEWUTS != 0) { ... // This is a file descriptor to an UTS namespace } ```
::::: #### Exemple shell {-} \ Dans un shell, nous utiliserons la commande `nsenter(1)` :
```bash 42sh# unshare --uts /bin/bash inutsns# echo $$ 42 inutsns# hostname jument # Keep this shell active to perform nexts steps, in another shell. 42sh# hostname chaton 42sh# nsenter --uts=/proc/42/ns/uts /bin/bash inutsns# hostname jument ```
Avec `nsenter(1)`, il est possible de cibler un processus particulier, sans aller nécessairement faire référence aux fichiers de `/proc`, en utilisant l'option `--target` :
```bash 42sh# unshare --uts /bin/bash inutsns# echo $$ 42 inutsns# hostname jument # Keep this shell active to perform nexts steps, in another shell. 42sh# hostname chaton 42sh# nsenter --target 42 --uts /bin/bash inutsns# hostname jument ```
Les options supplémentaires `--uts`, `--mount`, `--ipc`, `--pid`, ... ne prennent alors pas d'argument, mais désignent les espaces de noms du processus ciblé que l'on souhaite rejoindre.