setcifsacl: add fallback for when plugin can't be loaded
authorJeff Layton <jlayton@samba.org>
Thu, 18 Jul 2013 14:08:27 +0000 (10:08 -0400)
committerJeff Layton <jlayton@samba.org>
Thu, 18 Jul 2013 14:08:27 +0000 (10:08 -0400)
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>
setcifsacl.c

index 4b38459df1972d2e94cbe0badcb3e483fcd1484e..ce708eb077d6765ca85470e2c9dc6f9bc3e05b56 100644 (file)
@@ -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: