From 06a6ae94e6707d78a988784fe6a8a0f5f505322f Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Mon, 9 Mar 2009 20:05:15 +0000 Subject: [PATCH] Heavily modified patch from Gennadiy Nerubayev . Adds a pattern matching for initiator names to SCST access control. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@695 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/README | 8 ++++++- scst/README_in-tree | 8 ++++++- scst/src/scst_targ.c | 57 ++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 67 insertions(+), 6 deletions(-) diff --git a/scst/README b/scst/README index 3b0106817..735a6f803 100644 --- a/scst/README +++ b/scst/README @@ -436,7 +436,10 @@ following files and directories under /proc/scsi_tgt: for group "GROUP" - "add NAME" to /proc/scsi_tgt/groups/GROUP/names adds name "NAME" to group - "GROUP" + "GROUP". For NAME you can use simple DOS-type patterns, containing + '*' and '?' symbols. '*' means match all any symbols, '?' means + match only any single symbol. For instance, "blah.xxx" will match + "bl?h.*". - "del NAME" to /proc/scsi_tgt/groups/GROUP/names deletes name "NAME" from group "GROUP" @@ -454,6 +457,9 @@ Examples: add virtual VDISK device with name "disk1" to "Default" group with LUN 1. +- "echo "21:*:e0:?b:83:*'" >/proc/scsi_tgt/groups/LAB1/names" will + add a pattern, which matches WWNs of Fibre Channel ports from LAB1. + Consider you need to have an iSCSI target with name "iqn.2007-05.com.example:storage.disk1.sys1.xyz" (you defined it in iscsi-scst.conf), which should export virtual device "dev1" with LUN 0 diff --git a/scst/README_in-tree b/scst/README_in-tree index 015b003ac..a7fceb4bc 100644 --- a/scst/README_in-tree +++ b/scst/README_in-tree @@ -376,7 +376,10 @@ following files and directories under /proc/scsi_tgt: for group "GROUP" - "add NAME" to /proc/scsi_tgt/groups/GROUP/names adds name "NAME" to group - "GROUP" + "GROUP". For NAME you can use simple DOS-type patterns, containing + '*' and '?' symbols. '*' means match all any symbols, '?' means + match only any single symbol. For instance, "blah.xxx" will match + "bl?h.*". - "del NAME" to /proc/scsi_tgt/groups/GROUP/names deletes name "NAME" from group "GROUP" @@ -394,6 +397,9 @@ Examples: add virtual VDISK device with name "disk1" to "Default" group with LUN 1. +- "echo "21:*:e0:?b:83:*'" >/proc/scsi_tgt/groups/LAB1/names" will + add a pattern, which matches WWNs of Fibre Channel ports from LAB1. + Consider you need to have an iSCSI target with name "iqn.2007-05.com.example:storage.disk1.sys1.xyz" (you defined it in iscsi-scst.conf), which should export virtual device "dev1" with LUN 0 diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index a9bd93ca4..fd5c19346 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -5094,6 +5094,57 @@ out_free: } EXPORT_SYMBOL(scst_rx_mgmt_fn); +/* + * Returns true if string "string" matches pattern "wild", false otherwise. + * Pattern is a regular DOS-type pattern, containing '*' and '?' symbols. + * '*' means match all any symbols, '?' means match only any single symbol. + * + * For instance: + * if (wildcmp("bl?h.*", "blah.jpg")) { + * // match + * } else { + * // no match + * } + * + * Written by Jack Handy - jakkhandy@hotmail.com + * Taken by Gennadiy Nerubayev from + * http://www.codeproject.com/KB/string/wildcmp.aspx. No license attached + * to it, and is posted on a free site; assumed to be free for use. + */ +static bool wildcmp(const char *wild, const char *string) +{ + const char *cp = NULL, *mp = NULL; + + while ((*string) && (*wild != '*')) { + if ((*wild != *string) && (*wild != '?')) + return false; + + wild++; + string++; + } + + while (*string) { + if (*wild == '*') { + if (!*++wild) + return true; + + mp = wild; + cp = string+1; + } else if ((*wild == *string) || (*wild == '?')) { + wild++; + string++; + } else { + wild = mp; + string = cp++; + } + } + + while (*wild == '*') + wild++; + + return !*wild; +} + /* scst_mutex supposed to be held */ static struct scst_acg *scst_find_acg(const char *initiator_name) { @@ -5103,10 +5154,8 @@ static struct scst_acg *scst_find_acg(const char *initiator_name) TRACE_ENTRY(); list_for_each_entry(acg, &scst_acg_list, scst_acg_list_entry) { - list_for_each_entry(n, &acg->acn_list, - acn_list_entry) - { - if (strcmp(n->name, initiator_name) == 0) { + list_for_each_entry(n, &acg->acn_list, acn_list_entry) { + if (wildcmp(n->name, initiator_name)) { TRACE_DBG("Access control group %s found", acg->acg_name); res = acg;