From 712f6df225aa764d725257cccb38e9f869b50a4d Mon Sep 17 00:00:00 2001 From: ericm Date: Tue, 23 Aug 2005 03:48:48 +0000 Subject: [PATCH] add "blacklist" support into OSS capabilities. --- lustre/obdfilter/filter_capa.c | 91 ++++++++++++++++++++++++++++++++++++++ lustre/obdfilter/filter_internal.h | 3 ++ lustre/obdfilter/lproc_obdfilter.c | 37 ++++++++++++++++ 3 files changed, 131 insertions(+) diff --git a/lustre/obdfilter/filter_capa.c b/lustre/obdfilter/filter_capa.c index 9a3b813..1b3c718 100644 --- a/lustre/obdfilter/filter_capa.c +++ b/lustre/obdfilter/filter_capa.c @@ -34,6 +34,94 @@ #include "filter_internal.h" +/* + * FIXME + * keep this as simple as possible. we suppose the blacklist usually + * be empry or very short (<5), since long term blacklist should be + * done on MDS side. A more sophisticated blacklist will be implemented + * later. + * + * note blacklist didn't take effect when OSS capability disabled. this + * looks reasonable to me. + */ +#define BLACKLIST_MAX (32) +static int nblacklist = 0; +static uid_t blacklist[BLACKLIST_MAX]; +static spinlock_t blacklist_lock = SPIN_LOCK_UNLOCKED; + +int blacklist_display(char *buf, int bufsize) +{ + char one[16]; + int i; + LASSERT(buf); + + buf[0] = '\0'; + spin_lock(&blacklist_lock); + for (i = 0; i < nblacklist; i++) { + snprintf(one, 16, "%u\n", blacklist[i]); + strncat(buf, one, bufsize); + } + spin_unlock(&blacklist_lock); + return strnlen(buf, bufsize); +} + +void blacklist_add(uid_t uid) +{ + int i; + + spin_lock(&blacklist_lock); + if (nblacklist == BLACKLIST_MAX) { + CERROR("can't add more in blacklist\n"); + spin_unlock(&blacklist_lock); + return; + } + + for (i = 0; i < nblacklist; i++) { + if (blacklist[i] == uid) { + spin_unlock(&blacklist_lock); + return; + } + } + + blacklist[nblacklist++] = uid; + spin_unlock(&blacklist_lock); +} + +void blacklist_del(uid_t uid) +{ + int i; + + spin_lock(&blacklist_lock); + for (i = 0; i < nblacklist; i++) { + if (blacklist[i] == uid) { + nblacklist--; + while (i < nblacklist) { + blacklist[i] = blacklist[i+1]; + i++; + } + spin_unlock(&blacklist_lock); + return; + } + } + spin_unlock(&blacklist_lock); +} + +int blacklist_check(uid_t uid) +{ + int i, rc = 0; + + spin_lock(&blacklist_lock); + for (i = 0; i < nblacklist; i++) { + if (blacklist[i] == uid) { + rc = 1; + break; + } + } + spin_unlock(&blacklist_lock); + return rc; +} + + void filter_free_capa_keys(struct filter_obd *filter) { struct filter_capa_key *key, *n; @@ -139,6 +227,9 @@ filter_verify_capa(int cmd, struct obd_export *exp, struct lustre_capa *capa) if (capa == NULL) RETURN(-EACCES); + if (blacklist_check(capa->lc_uid)) + RETURN(-EACCES); + if (cmd == OBD_BRW_WRITE && capa->lc_op != MAY_WRITE) RETURN(-EACCES); if (cmd == OBD_BRW_READ && !(capa->lc_op & (MAY_WRITE | MAY_READ))) diff --git a/lustre/obdfilter/filter_internal.h b/lustre/obdfilter/filter_internal.h index d6140a7..33b13a1 100644 --- a/lustre/obdfilter/filter_internal.h +++ b/lustre/obdfilter/filter_internal.h @@ -197,6 +197,9 @@ static inline lproc_filter_attach_seqstat(struct obd_device *dev) {} #endif /* filter_capa.c */ +void blacklist_add(uid_t uid); +void blacklist_del(uid_t uid); +int blacklist_display(char *buf, int bufsize); int filter_init_capa_keys(struct obd_device *obd); void filter_free_capa_keys(struct filter_obd *filter); int filter_update_capa_key(struct obd_device *obd, struct lustre_capa_key *key); diff --git a/lustre/obdfilter/lproc_obdfilter.c b/lustre/obdfilter/lproc_obdfilter.c index fa170d7..5cd3e6b 100644 --- a/lustre/obdfilter/lproc_obdfilter.c +++ b/lustre/obdfilter/lproc_obdfilter.c @@ -160,6 +160,41 @@ int lprocfs_filter_wr_capa_stat(struct file *file, const char *buffer, return count; } +static +int lprocfs_filter_rd_blacklist(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + int rc; + + rc = blacklist_display(page, count); + *eof = 1; + return rc; +} + +static +int lprocfs_filter_wr_blacklist(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int add; + uid_t uid = -1; + + if (count < 2) + return count; + if (buffer[0] == '+') + add = 1; + else if (buffer[0] == '-') + add = 0; + else + return count; + + sscanf(buffer + 1, "%u", &uid); + if (add) + blacklist_add(uid); + else + blacklist_del(uid); + return count; +} + static struct lprocfs_vars lprocfs_obd_vars[] = { { "uuid", lprocfs_rd_uuid, 0, 0 }, { "blocksize", lprocfs_rd_blksize, 0, 0 }, @@ -182,6 +217,8 @@ static struct lprocfs_vars lprocfs_obd_vars[] = { { "recovery_status", lprocfs_obd_rd_recovery_status, 0, 0 }, { "capa", lprocfs_filter_rd_capa_stat, lprocfs_filter_wr_capa_stat, 0 }, + { "blacklist", lprocfs_filter_rd_blacklist, + lprocfs_filter_wr_blacklist, 0 }, { 0 } }; -- 1.8.3.1