diff options
author | Jeff Layton <jlayton@samba.org> | 2013-07-18 10:08:27 -0400 |
---|---|---|
committer | Jeff Layton <jlayton@samba.org> | 2013-07-18 10:08:27 -0400 |
commit | fe230e5ecaed98d3bb70292b60d44c3c7c47c720 (patch) | |
tree | 4972d474b5b3ba3dfad885293310b318608f7dd5 | |
parent | 9fd9f71afc8a849df97973764227d6a13f2768f3 (diff) | |
download | cifs-utils-fe230e5ecaed98d3bb70292b60d44c3c7c47c720.tar.gz cifs-utils-fe230e5ecaed98d3bb70292b60d44c3c7c47c720.tar.bz2 cifs-utils-fe230e5ecaed98d3bb70292b60d44c3c7c47c720.zip |
setcifsacl: add fallback for when plugin can't be loaded
Allow setcifsacl to function even in the case where the plugin can't
be initialized. ID mapping of course won't work, but we can still allow
it to accept "raw" SID strings.
Signed-off-by: Jeff Layton <jlayton@samba.org>
-rw-r--r-- | setcifsacl.c | 92 |
1 files changed, 87 insertions, 5 deletions
diff --git a/setcifsacl.c b/setcifsacl.c index 4b38459..ce708eb 100644 --- a/setcifsacl.c +++ b/setcifsacl.c @@ -48,6 +48,7 @@ enum setcifsacl_actions { }; static void *plugin_handle; +static bool plugin_loaded; static void copy_cifs_sid(struct cifs_sid *dst, const struct cifs_sid *src) @@ -534,6 +535,83 @@ verify_ace_mask(char *maskstr, uint32_t *maskval) return 0; } +#define AUTHORITY_MASK (~(0xffffffffffffULL)) + +static int +raw_str_to_sid(const char *str, struct cifs_sid *csid) +{ + const char *p; + char *q; + unsigned long long x; + + /* Sanity check for either "S-" or "s-" */ + if ((str[0] != 'S' && str[0] != 's') || (str[1]!='-')) { + plugin_errmsg = "SID string does not start with \"S-\""; + return -EINVAL; + } + + /* Get the SID revision number */ + p = str + 2; + x = strtoull(p, &q, 10); + if (x == 0 || x > UCHAR_MAX || !q || *q != '-') { + plugin_errmsg = "Invalid SID revision number"; + return -EINVAL; + } + csid->revision = (uint8_t)x; + + /* + * Next the Identifier Authority. This is stored in big-endian in a + * 6 byte array. If the authority value is > UINT_MAX, then it should + * be expressed as a hex value. + */ + p = q + 1; + x = strtoull(p, &q, 0); + if ((x & AUTHORITY_MASK) || !q || *q !='-') { + plugin_errmsg = "Invalid SID authority"; + return -EINVAL; + } + csid->authority[5] = (x & 0x0000000000ffULL); + csid->authority[4] = (x & 0x00000000ff00ULL) >> 8; + csid->authority[3] = (x & 0x000000ff0000ULL) >> 16; + csid->authority[2] = (x & 0x0000ff000000ULL) >> 24; + csid->authority[1] = (x & 0x00ff00000000ULL) >> 32; + csid->authority[0] = (x & 0xff0000000000ULL) >> 48; + + /* now read the the subauthorities and store as __le32 vals */ + p = q + 1; + csid->num_subauth = 0; + while (csid->num_subauth < SID_MAX_SUB_AUTHORITIES) { + x = strtoul(p, &q, 10); + if (p == q) + break; + if (x > UINT_MAX) { + plugin_errmsg = "Invalid sub authority value"; + return -EINVAL; + } + csid->sub_auth[csid->num_subauth++] = htole32((uint32_t)x); + + if (*q != '-') + break; + p = q + 1; + } + + /* IF we ended early, then the SID could not be converted */ + if (q && *q != '\0') { + plugin_errmsg = "Invalid sub authority value"; + return -EINVAL; + } + + return 0; +} + +static int +setcifsacl_str_to_sid(const char *str, struct cifs_sid *sid) +{ + if (plugin_loaded) + return str_to_sid(plugin_handle, str, sid); + return raw_str_to_sid(str, sid); +} + static struct cifs_ace ** build_cmdline_aces(char **arrptr, int numcaces) { @@ -564,7 +642,7 @@ build_cmdline_aces(char **arrptr, int numcaces) goto build_cmdline_aces_ret; } - if (str_to_sid(plugin_handle, acesid, &cacesptr[i]->sid)) { + if (setcifsacl_str_to_sid(acesid, &cacesptr[i]->sid)) { printf("%s: Invalid SID (%s): %s\n", __func__, arrptr[i], plugin_errmsg); goto build_cmdline_aces_ret; @@ -765,9 +843,12 @@ main(const int argc, char *const argv[]) } if (init_plugin(&plugin_handle)) { - printf("ERROR: unable to initialize idmapping plugin: %s\n", - plugin_errmsg); - return -1; + fprintf(stderr, "WARNING: unable to initialize idmapping " + "plugin. Only \"raw\" SID strings will be " + "accepted: %s\n", plugin_errmsg); + plugin_loaded = false; + } else { + plugin_loaded = true; } numcaces = get_numcaces(ace_list); @@ -827,7 +908,8 @@ cifsacl: goto setcifsacl_facenum_ret; } - exit_plugin(plugin_handle); + if (plugin_loaded) + exit_plugin(plugin_handle); return 0; setcifsacl_action_ret: |