システムコール mkdir() を変更して、ディレクトリを作成させたくない一部のユーザーをフィルタリングしようとしています。これは最もエレガントな方法ではないかもしれませんが、なぜ機能しないのか知りたいです。
mkdir() の置き換えコードは次のとおりです。
#define _GNU_SOURCE
#define MAXGRUPOS 30
#define dim(x) (sizeof(x)/sizeof(x[0]))
#define true 1
#define false 0
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
//
//Me permite llamar al metodo original
#include <dlfcn.h>
//codigos de error
#include <errno.h>
//mkdir()
#include <sys/stat.h>
#include <sys/types.h>
//para obtener los usuarios
#include <unistd.h>
//parser de la config
#include <libconfig.h>
//#####################################################
#define RUTA_CONFIG "/etc/samba/gruposhabilitados.txt"
//#####################################################
int *obtenerGruposValidos(){
int indice = 1;
int (*gruposValidos) = malloc(sizeof (int) * MAXGRUPOS);
config_t cfg, *cf;
const config_setting_t *grupos;
int count = 0, n = 0, activo = 0;
//add root
gruposValidos[0]=0;
//init parser
cf = &cfg;
config_init(cf);
if (!config_read_file(cf, RUTA_CONFIG )) {
puts("ERROR al parsear\n");
config_destroy(cf);
return gruposValidos;
}
if(config_lookup_bool(cf, "Carpetas.activo", &activo)){
if( activo == 0 ){
config_destroy(cf);
gruposValidos[1] = (int) getgid();
return gruposValidos;
}//if
else{
grupos = config_lookup(cf, "Carpetas.gruposHabilitados");
count = config_setting_length(grupos);
for (n = 0; n < count; n++) {
printf("Grupo: %d\n", (int) config_setting_get_int_elem(grupos, n));
gruposValidos[n+1] = ((int) config_setting_get_int_elem(grupos, n));
}
config_destroy(cf);
}//else
}//if
indice = n+1;
while ( indice < MAXGRUPOS )
gruposValidos[indice++] = -1;
return gruposValidos;
}//obtenerGruposValidos
int verificarGrupos(void){
gid_t gids[MAXGRUPOS];
int *gruposValidos = obtenerGruposValidos();
int count, curr, aux;
if ((count = getgroups(dim(gids), gids)) == -1){
perror("getgroups() error");
return false;
}
else {
fflush(NULL);//me tiraba un error sin esto
for (curr=0; curr<count; curr++){
for(aux=0; aux < MAXGRUPOS; aux++){
printf("%i-%i) Guid: %d - grupoValido: %d\n",curr,aux,((int) gids[curr]) ,(int) ((gruposValidos)[aux]));
if (((int) gids[curr]) == ((int) ((gruposValidos)[aux]) )){
free(gruposValidos);
return true;
}//if
}//for
}//for
free(gruposValidos);
return false;
}//else
}
int mkdir(const char *pathname, mode_t mode){
int habilitadoAEscribir = false;
puts("FALSE MKDIR");
habilitadoAEscribir = verificarGrupos();
if ( habilitadoAEscribir == true ){
int (*mkdir_real)(const char *pathname, mode_t mode);
mkdir_real = dlsym(RTLD_NEXT,"mkdir");
mkdir_real(pathname, mode);
return 0;
}
else{
errno=EPERM;
return(errno);
}
}
int rmdir(const char *pathname){
int habilitadoAEscribir = false;
habilitadoAEscribir = verificarGrupos();
if ( habilitadoAEscribir == true ){
int (*rmdir_real)(const char *pathname);
rmdir_real = dlsym(RTLD_NEXT,"rmdir");
rmdir_real(pathname);
return 0;
}
else{
errno=EPERM;
return(errno);
}
}
-Wall -std=c99 -fPIC -lconfig -ldl -shared でコンパイル
mkdirバイナリで使用すると、完全に機能します
LD_PRELOAD=wrapper.so /bin/mkdir ディレクトリ
しかし、私がこのように使用すると:
LD_PRELOAD=wrapper.so bindfs AB my mkdir() は使用されません。
この実装を試してみましたが、私のニーズをカバーしていませんが、binfs で動作します
#include <errno.h>
int mkdir() { errno = EPERM; return -1; }
int rmdir() { errno = EPERM; return -1; }