diff options
author | Jeff Layton <jlayton@samba.org> | 2012-11-07 10:19:19 -0500 |
---|---|---|
committer | Jeff Layton <jlayton@samba.org> | 2012-11-07 10:19:19 -0500 |
commit | 6a091a5aa6fd9de3e2ea700896e1949a5623b1c6 (patch) | |
tree | 2f64542042cb2a7567571424f526a76775d952f6 | |
parent | 3a41103dfea64856c8317099496716a7f9010769 (diff) | |
download | cifs-utils-6a091a5aa6fd9de3e2ea700896e1949a5623b1c6.tar.gz cifs-utils-6a091a5aa6fd9de3e2ea700896e1949a5623b1c6.tar.bz2 cifs-utils-6a091a5aa6fd9de3e2ea700896e1949a5623b1c6.zip |
setcifsacl: fix up ACE mask handling
Change verify_ace_mask to just attempt to convert the argument to an
unsigned long first. If that fails, then try to treat it as a symbolic
mask string.
Also, clean up ace_mask_value. There's no need to walk the string
twice. Walk it once and turn the single-char mask checks into a switch
statement instead of if/else clauses.
Finally, fix the endianness of the resulting value. It must be in LE.
Signed-off-by: Jeff Layton <jlayton@samba.org>
-rw-r--r-- | setcifsacl.c | 81 |
1 files changed, 40 insertions, 41 deletions
diff --git a/setcifsacl.c b/setcifsacl.c index 37e95e2..3178eff 100644 --- a/setcifsacl.c +++ b/setcifsacl.c @@ -512,62 +512,61 @@ verify_ace_flags(char *flagstr, uint8_t *flagval) } static uint32_t -ace_mask_value(char *maskstr) +ace_mask_value(char *mask) { - int i, len; - uint32_t maskval = 0x0; - char *lmask; + uint32_t maskval = 0; + char cur; - if (!strcmp(maskstr, "FULL")) + if (!strcmp(mask, "FULL")) return FULL_CONTROL; - else if (!strcmp(maskstr, "CHANGE")) + if (!strcmp(mask, "CHANGE")) return CHANGE; - else if (!strcmp(maskstr, "D")) - return DELETE; - else if (!strcmp(maskstr, "READ")) + if (!strcmp(mask, "READ")) return EREAD; - else { - len = strlen(maskstr); - lmask = maskstr; - for (i = 0; i < len; ++i, ++lmask) { - if (*lmask == 'R') - maskval |= EREAD; - else if (*lmask == 'W') - maskval |= EWRITE; - else if (*lmask == 'X') - maskval |= EXEC; - else if (*lmask == 'D') - maskval |= DELETE; - else if (*lmask == 'P') - maskval |= WRITE_DAC; - else if (*lmask == 'O') - maskval |= WRITE_OWNER; - else - return 0; + + while((cur = *mask++)) { + switch(cur) { + case 'R': + maskval |= EREAD; + break; + case 'W': + maskval |= EWRITE; + break; + case 'X': + maskval |= EXEC; + break; + case 'D': + maskval |= DELETE; + break; + case 'P': + maskval |= WRITE_DAC; + break; + case 'O': + maskval |= WRITE_OWNER; + break; + default: + return 0; } - return maskval; } - - return 0; + return maskval; } static int verify_ace_mask(char *maskstr, uint32_t *maskval) { - char *invalflag; + unsigned long val; + char *ep; - if (strstr(maskstr, "0x") || !strcmp(maskstr, "DELDHLD")) { - *maskval = strtol(maskstr, &invalflag, 16); - if (!invalflag) { - printf("%s: Invalid mask: %s\n", __func__, maskstr); - return 1; - } - } else - *maskval = ace_mask_value(maskstr); + errno = 0; + val = strtoul(maskstr, &ep, 0); + if (errno == 0 && *ep == '\0') + *maskval = htole32((uint32_t)val); + else + *maskval = htole32(ace_mask_value(maskstr)); if (!*maskval) { - printf("%s: Invalid mask %s and value: 0x%x\n", - __func__, maskstr, *maskval); + printf("%s: Invalid mask %s (value 0x%x)\n", __func__, + maskstr, *maskval); return 1; } |