diff -ruN clamav-0.100.2/clamd/server-th.c clamav-0.100.2.pr51/clamd/server-th.c
--- clamav-0.100.2/clamd/server-th.c	2018-09-19 15:29:07.000000000 -0400
+++ clamav-0.100.2.pr51/clamd/server-th.c	2018-11-27 09:56:25.669608091 -0500
@@ -1063,6 +1063,9 @@
 	val = cl_engine_get_num(engine, CL_ENGINE_MIN_CC_COUNT, NULL);
 	logg("Structured: Minimum Credit Card Number Count set to %u\n", (unsigned int) val);
 
+    if(optget(opts, "StructuredCCOnly")->enabled)
+        options |= CL_SCAN_STRUCTURED_CC_ONLY;
+
 	if((opt = optget(opts, "StructuredMinSSNCount"))->enabled) {
 	    if((ret = cl_engine_set_num(engine, CL_ENGINE_MIN_SSN_COUNT, opt->numarg))) {
 		logg("!cl_engine_set_num(CL_ENGINE_MIN_SSN_COUNT) failed: %s\n", cl_strerror(ret));
diff -ruN clamav-0.100.2/clamscan/clamscan.c clamav-0.100.2.pr51/clamscan/clamscan.c
--- clamav-0.100.2/clamscan/clamscan.c	2018-09-19 15:29:07.000000000 -0400
+++ clamav-0.100.2.pr51/clamscan/clamscan.c	2018-11-27 09:56:25.670576915 -0500
@@ -250,6 +250,7 @@
     mprintf("    --structured-ssn-format=X            SSN format (0=normal,1=stripped,2=both)\n");
     mprintf("    --structured-ssn-count=N             Min SSN count to generate a detect\n");
     mprintf("    --structured-cc-count=N              Min CC count to generate a detect\n");
+    mprintf("    --structured-cc-mode=X               CC mode (0=credit debit and private label, 1=credit cards only\n");
     mprintf("    --scan-mail[=yes(*)/no]              Scan mail files\n");
     mprintf("    --phishing-sigs[=yes(*)/no]          Signature-based phishing detection\n");
     mprintf("    --phishing-scan-urls[=yes(*)/no]     URL-based phishing detection\n");
diff -ruN clamav-0.100.2/clamscan/manager.c clamav-0.100.2.pr51/clamscan/manager.c
--- clamav-0.100.2/clamscan/manager.c	2018-09-19 15:29:07.000000000 -0400
+++ clamav-0.100.2.pr51/clamscan/manager.c	2018-11-27 09:56:25.670576915 -0500
@@ -1117,6 +1117,19 @@
                 return 2;
             }
         }
+        
+        if((opt = optget(opts, "structured-cc-mode"))->active) {
+            switch(opt->numarg) {
+                case 0:
+                    break;
+                case 1:
+                    options |= CL_SCAN_STRUCTURED_CC_ONLY;
+                    break;
+                default:
+                    logg("!Invalid argument for --structured-cc-mode\n");
+                    return 2;
+            }
+        }
     } else {
         options &= ~CL_SCAN_STRUCTURED;
     }
diff -ruN clamav-0.100.2/docs/man/clamd.conf.5.in clamav-0.100.2.pr51/docs/man/clamd.conf.5.in
--- clamav-0.100.2/docs/man/clamd.conf.5.in	2018-09-19 15:29:07.000000000 -0400
+++ clamav-0.100.2.pr51/docs/man/clamd.conf.5.in	2018-11-27 09:56:25.670576915 -0500
@@ -414,6 +414,11 @@
 .br 
 Default: 3
 .TP
+\fBStructuredCCOnly BOOL\fR
+With this option enabled the DLP module will search for valid Credit Card\nnumbers only. Debit and Private Label cards will not be searched.
+.br 
+Default: No
+.TP
 \fBStructuredMinSSNCount NUMBER\fR
 This option sets the lowest number of Social Security Numbers found in a file to generate a detect.
 .br 
diff -ruN clamav-0.100.2/etc/clamd.conf.sample clamav-0.100.2.pr51/etc/clamd.conf.sample
--- clamav-0.100.2/etc/clamd.conf.sample	2018-09-19 15:29:07.000000000 -0400
+++ clamav-0.100.2.pr51/etc/clamd.conf.sample	2018-11-27 09:56:25.671545738 -0500
@@ -412,6 +412,11 @@
 # Default: 3
 #StructuredMinCreditCardCount 5
 
+# With this option enabled the DLP module will search for valid Credit Card
+# numbers only. Debit and Private Label cards will not be searched.
+# Default: no
+#StructuredCCOnly yes
+
 # This option sets the lowest number of Social Security Numbers found
 # in a file to generate a detect.
 # Default: 3
diff -ruN clamav-0.100.2/libclamav/clamav.h clamav-0.100.2.pr51/libclamav/clamav.h
--- clamav-0.100.2/libclamav/clamav.h	2018-09-19 15:29:07.000000000 -0400
+++ clamav-0.100.2.pr51/libclamav/clamav.h	2018-11-27 09:56:25.671545738 -0500
@@ -173,7 +173,7 @@
 #define CL_SCAN_XMLDOCS                 0x1000000
 #define CL_SCAN_HWP3                    0x2000000
 #define CL_SCAN_FILE_PROPERTIES         0x10000000
-//#define UNUSED                        0x20000000
+#define CL_SCAN_STRUCTURED_CC_ONLY      0x20000000
 #define CL_SCAN_PERFORMANCE_INFO        0x40000000 /* collect performance timings */
 #define CL_SCAN_INTERNAL_COLLECT_SHA    0x80000000 /* Enables hash output in sha-collect builds - for internal use only */
 
diff -ruN clamav-0.100.2/libclamav/dlp.c clamav-0.100.2.pr51/libclamav/dlp.c
--- clamav-0.100.2/libclamav/dlp.c	2018-09-19 15:29:07.000000000 -0400
+++ clamav-0.100.2.pr51/libclamav/dlp.c	2018-11-27 09:56:25.674452209 -0500
@@ -128,34 +128,35 @@
 struct iin_map_struct {
     uint32_t iin_start;
     uint32_t iin_end;
-    uint8_t card_len;
+    uint8_t card_min;
+    uint8_t card_max;
+    uint8_t is_cc;
     uint8_t luhn;
     const char* iin_name;
 };
 
-/* Maestro card range, 550000-699999, encompasses ranges
-   of several other cards including Discover and UnionPay.
-*/
-
 static struct iin_map_struct iin_map[] = {
-    {100000, 199999, 15, 1, "UATP"},
-    {300000, 305999, 14, 1, "Diner's Club - Carte Blanche"},
-    {309500, 309599, 14, 1, "Diner's Club International"},
-    {340000, 349999, 15, 1, "American Express"},
-    {352800, 358999, 16, 1, "JCB"},
-    {360000, 369999, 14, 1, "Diner's Club International"},
-    {370000, 379999, 15, 1, "American Express"},
-    {380000, 399999, 16, 1, "Diner's Club International"},
-    {400000, 499999, 16, 1, "Visa"},
-    {500000, 509999, 16, 1, "Maestro"},
-    {510000, 559999, 16, 1, "Master Card"},
-    {560000, 699999, 16, 1, "Maestro/Discover/UnionPay/etc."},
+    {100000, 199999, 13, 15, 0, 1, "UATP"},
+    {222100, 272099, 16, 16, 1, 1, "Mastercard 2016"},
+    {300000, 305999, 14, 16, 1, 1, "Diner's Club - Carte Blanche"},
+    {309500, 309599, 14, 16, 1, 1, "Diner's Club International"},
+    {340000, 349999, 15, 15, 1, 1, "American Express"},
+    {352800, 358999, 16, 16, 1, 1, "JCB"},
+    {360000, 369999, 14, 16, 1, 1, "Diner's Club International"},
+    {370000, 379999, 15, 15, 1, 1, "American Express"},
+    {380000, 399999, 16, 16, 1, 1, "Diner's Club International"},
+    {400000, 499999, 16, 16, 1, 1, "Visa"},
+    {500000, 509999, 16, 16, 0, 1, "Maestro"},
+    {510000, 559999, 16, 16, 1, 1, "Master Card"},
+    {601100, 601199, 16, 16, 1, 1, "Discover"},
+    {622126, 622926, 16, 16, 1, 1, "China Union Pay"},
+    {624000, 626999, 16, 16, 1, 1, "China Union Pay"},
+    {628200, 628899, 16, 16, 1, 1, "China Union Pay"},
+    {644000, 659999, 16, 16, 1, 1, "Discover 2009"},
     {0}
 };
 
-/* Fixme: some card ranges can have lengths other than 16 */
-
-static const struct iin_map_struct * get_iin(char * digits)
+static const struct iin_map_struct * get_iin(char * digits, int cc_only)
 {
     int iin = atoi(digits);
     int i = 0;
@@ -163,7 +164,7 @@
     while (iin_map[i].iin_start != 0) {
         if (iin < iin_map[i].iin_start)
             break;
-        if (iin <= iin_map[i].iin_end) {
+        if (iin <= iin_map[i].iin_end && (cc_only == 0 || iin_map[i].is_cc == 1)) {
             cli_dbgmsg("Credit card IIN %s matched range for %s\n", digits, iin_map[i].iin_name);
             return &iin_map[i];
         }
@@ -173,7 +174,7 @@
     return NULL;
 }
 
-int dlp_is_valid_cc(const unsigned char *buffer, int length)
+int dlp_is_valid_cc(const unsigned char *buffer, int length, int cc_only)
 {
     int mult = 0;
     int sum = 0;
@@ -215,12 +216,12 @@
         return 0;
 
     /* See if it is a valid IIN. */ 
-    iin = get_iin(cc_digits);
+    iin = get_iin(cc_digits, cc_only);
     if (iin == NULL)
          return 0;
 
     /* Look for the remaining needed digits. */
-    for (/*same 'i' from previous for-loop*/; i < length && digits < iin->card_len; i++) {
+    for (/*same 'i' from previous for-loop*/; i < length && digits < iin->card_max; i++) {
 	if(isdigit(buffer[i]) == 0) {
             if(buffer[i] == ' ' || buffer[i] == '-')
                 if (pad_allowance-- > 0)
@@ -232,7 +233,7 @@
     }
 
     // should be !isdigit(buffer[i]) ?
-    if(digits < 13 || (i < length && isdigit(buffer[i])))
+    if(digits < iin->card_min || (i < length && isdigit(buffer[i])))
 	return 0;
 
     //figure out luhn digits 
@@ -255,7 +256,7 @@
     return 1;
 }
 
-static int contains_cc(const unsigned char *buffer, int length, int detmode)
+static int contains_cc(const unsigned char *buffer, int length, int detmode, int cc_only)
 {
     const unsigned char *idx;
     const unsigned char *end;
@@ -272,7 +273,7 @@
     {
         if(isdigit(*idx))
         {
-            if((idx == buffer || !isdigit(idx[-1])) && dlp_is_valid_cc(idx, length - (idx - buffer)) == 1)
+            if((idx == buffer || !isdigit(idx[-1])) && dlp_is_valid_cc(idx, length - (idx - buffer), cc_only) == 1)
             {
                 if(detmode == DETECT_MODE_DETECT)
                     return 1;
@@ -292,14 +293,14 @@
     return count;
 }
 
-int dlp_get_cc_count(const unsigned char *buffer, int length)
+int dlp_get_cc_count(const unsigned char *buffer, int length, int cc_only)
 {
-    return contains_cc(buffer, length, DETECT_MODE_COUNT);
+    return contains_cc(buffer, length, DETECT_MODE_COUNT, cc_only);
 }
 
-int dlp_has_cc(const unsigned char *buffer, int length)
+int dlp_has_cc(const unsigned char *buffer, int length, int cc_only)
 {
-    return contains_cc(buffer, length, DETECT_MODE_DETECT);
+    return contains_cc(buffer, length, DETECT_MODE_DETECT, cc_only);
 }
 
 int dlp_is_valid_ssn(const unsigned char *buffer, int length, int format)
diff -ruN clamav-0.100.2/libclamav/dlp.h clamav-0.100.2.pr51/libclamav/dlp.h
--- clamav-0.100.2/libclamav/dlp.h	2018-09-19 15:29:07.000000000 -0400
+++ clamav-0.100.2.pr51/libclamav/dlp.h	2018-11-27 09:56:25.671545738 -0500
@@ -38,30 +38,33 @@
  *      buffer => data buffer to be validated.
  *      length => length of supplied buffer.  Values greater than 16 are
  *                truncated to 16.  Values less than 13 are rejected. 
+ *      cc_only => Only check for credit cards, not debit or private label.
  * Returns:
  *      1 on a find, 0 on a miss
  */
-int dlp_is_valid_cc(const unsigned char *buffer, int length);
+int dlp_is_valid_cc(const unsigned char *buffer, int length, int cc_only);
 
 /* Searches the supplied buffer for credit card numbers and returns
  * the number of CC's found.
  * Params:
  *      buffer => data buffer to be analyzed.
  *      length => length of buffer.  
+ *      cc_only => Only check for credit cards, not debit or private label.
  * Returns:
  *      Count of detected CC #'s.
  */
-int dlp_get_cc_count(const unsigned char *buffer, int length);
+int dlp_get_cc_count(const unsigned char *buffer, int length, int cc_only);
 
 /* Searches the supplied buffer for CC #'s.  Bails out as soon as a 
  * validated number is detected.
  * Params:
  *      buffer => data buffer to be analyzed.
  *      length => length of buffer.
+ *      cc_only => Only check for credit cards, not debit or private label.
  * Returns:
  *      1 on detect, 0 on fail
  */
-int dlp_has_cc(const unsigned char *buffer, int length);
+int dlp_has_cc(const unsigned char *buffer, int length, int cc_only);
 
 /* Checks the supplied buffer for a valid SSN number.  Validation
  * is supplied via area and group number validation.  Valid numbers
diff -ruN clamav-0.100.2/libclamav/scanners.c clamav-0.100.2.pr51/libclamav/scanners.c
--- clamav-0.100.2/libclamav/scanners.c	2018-09-19 15:29:07.000000000 -0400
+++ clamav-0.100.2.pr51/libclamav/scanners.c	2018-11-27 09:57:50.306674884 -0500
@@ -2040,7 +2040,7 @@
     int done = 0;
     fmap_t *map;
     size_t pos = 0;
-    int (*ccfunc)(const unsigned char *buffer, int length);
+    int (*ccfunc)(const unsigned char *buffer, int length, int cc_only);
     int (*ssnfunc)(const unsigned char *buffer, int length);
     unsigned int viruses_found = 0;
 
@@ -2085,7 +2085,7 @@
     while (!done && ((result = fmap_readn(map, buf, pos, 8191)) > 0))
     {
         pos += result;
-        if ((cc_count += ccfunc((const unsigned char *)buf, result)) >= ctx->engine->min_cc_count)
+        if ((cc_count += ccfunc((const unsigned char *)buf, result, (ctx->options & CL_SCAN_STRUCTURED_CC_ONLY)?1:0)) >= ctx->engine->min_cc_count)
         {
             done = 1;
         }
diff -ruN clamav-0.100.2/shared/optparser.c clamav-0.100.2.pr51/shared/optparser.c
--- clamav-0.100.2/shared/optparser.c	2018-09-19 15:29:07.000000000 -0400
+++ clamav-0.100.2.pr51/shared/optparser.c	2018-11-27 09:56:25.673483386 -0500
@@ -336,6 +336,8 @@
 
     { "StructuredMinCreditCardCount", "structured-cc-count", 0, CLOPT_TYPE_NUMBER, MATCH_NUMBER, CLI_DEFAULT_MIN_CC_COUNT, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option sets the lowest number of Credit Card numbers found in a file\nto generate a detect.", "5" },
 
+    { "StructuredCCOnly", NULL, 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD, "With this option enabled the DLP module will search for valid Credit Card\nnumbers only. Debit and Private Label cards will not be searched.", "no" },
+
     { "StructuredMinSSNCount", "structured-ssn-count", 0, CLOPT_TYPE_NUMBER, MATCH_NUMBER, CLI_DEFAULT_MIN_SSN_COUNT, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option sets the lowest number of Social Security Numbers found\nin a file to generate a detect.", "5" },
 
     { "StructuredSSNFormatNormal", NULL, 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 1, NULL, 0, OPT_CLAMD, "With this option enabled the DLP module will search for valid\nSSNs formatted as xxx-yy-zzzz.", "yes" },
