Added ability to set id mappings in wbinfo.
authorSteven Danneman <steven.danneman@isilon.com>
Tue, 28 Oct 2008 06:46:44 +0000 (23:46 -0700)
committerSteven Danneman <steven.danneman@isilon.com>
Wed, 19 Nov 2008 00:04:03 +0000 (16:04 -0800)
The two new parameters are:

--set-uid-mapping
--set-gid-mapping

These allow wbinfo to create new, or override existing id mappings in the
idmap backend.  These expose the exisiting ability of libwbclient
and winbindd to do this, up through a command line utility.

source3/nsswitch/wbinfo.c

index 84f01e19ff229d4b0e98de2863241f2a42ccc5d3..27df52f92c911a7720c0a5ba84609d1ecd53c66f 100644 (file)
@@ -130,6 +130,31 @@ static bool parse_wbinfo_domain_user(const char *domuser, fstring domain,
        return true;
 }
 
+/* Parse string of "uid,sid" or "gid,sid" into separate int and string values.
+ * Return true if input was valid, false otherwise. */
+static bool parse_mapping_arg(char *arg, int *id, char **sid)
+{
+       char *tmp, *endptr;
+
+       if (!arg || !*arg)
+               return false;
+
+       tmp = strtok(arg, ",");
+       *sid = strtok(NULL, ",");
+
+       if (!tmp || !*tmp || !*sid || !**sid)
+               return false;
+
+       /* Because atoi() can return 0 on invalid input, which would be a valid
+        * UID/GID we must use strtol() and do error checking */
+       *id = strtol(tmp, &endptr, 10);
+
+       if (endptr[0] != '\0')
+               return false;
+
+       return true;
+}
+
 /* pull pwent info for a given user */
 
 static bool wbinfo_get_userinfo(char *user)
@@ -738,6 +763,54 @@ static bool wbinfo_allocate_gid(void)
        return true;
 }
 
+static bool wbinfo_set_uid_mapping(uid_t uid, const char *sid_str)
+{
+       wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+       struct wbcDomainSid sid;
+
+       /* Send request */
+
+       wbc_status = wbcStringToSid(sid_str, &sid);
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
+               return false;
+       }
+
+       wbc_status = wbcSetUidMapping(uid, &sid);
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
+               return false;
+       }
+
+       /* Display response */
+
+       d_printf("uid %d now mapped to sid %s\n", uid, sid_str);
+
+       return true;
+}
+
+static bool wbinfo_set_gid_mapping(gid_t gid, const char *sid_str)
+{
+       wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+       struct wbcDomainSid sid;
+
+       /* Send request */
+
+       wbc_status = wbcStringToSid(sid_str, &sid);
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
+               return false;
+       }
+
+       wbc_status = wbcSetGidMapping(gid, &sid);
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
+               return false;
+       }
+
+       /* Display response */
+
+       d_printf("gid %d now mapped to sid %s\n", gid, sid_str);
+
+       return true;
+}
+
 /* Convert sid to string */
 
 static bool wbinfo_lookupsid(const char *sid_str)
@@ -1414,6 +1487,8 @@ enum {
        OPT_USERSIDS,
        OPT_ALLOCATE_UID,
        OPT_ALLOCATE_GID,
+       OPT_SET_UID_MAPPING,
+       OPT_SET_GID_MAPPING,
        OPT_SEPARATOR,
        OPT_LIST_ALL_DOMAINS,
        OPT_LIST_OWN_DOMAIN,
@@ -1431,8 +1506,10 @@ int main(int argc, char **argv, char **envp)
        TALLOC_CTX *frame = talloc_stackframe();
        poptContext pc;
        static char *string_arg;
+       char *string_subarg = NULL;
        static char *opt_domain_name;
        static int int_arg;
+       int int_subarg = -1;
        int result = 1;
        bool verbose = false;
 
@@ -1459,6 +1536,8 @@ int main(int argc, char **argv, char **envp)
                  "Get a new UID out of idmap" },
                { "allocate-gid", 0, POPT_ARG_NONE, 0, OPT_ALLOCATE_GID,
                  "Get a new GID out of idmap" },
+               { "set-uid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_SET_UID_MAPPING, "Create or modify uid to sid mapping in idmap", "UID,SID" },
+               { "set-gid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_SET_GID_MAPPING, "Create or modify gid to sid mapping in idmap", "GID,SID" },
                { "check-secret", 't', POPT_ARG_NONE, 0, 't', "Check shared secret" },
                { "trusted-domains", 'm', POPT_ARG_NONE, 0, 'm', "List trusted domains" },
                { "all-domains", 0, POPT_ARG_NONE, 0, OPT_LIST_ALL_DOMAINS, "List all domains (trusted and own domain)" },
@@ -1627,6 +1706,26 @@ int main(int argc, char **argv, char **envp)
                                goto done;
                        }
                        break;
+               case OPT_SET_UID_MAPPING:
+                       if (!parse_mapping_arg(string_arg, &int_subarg,
+                               &string_subarg) ||
+                           !wbinfo_set_uid_mapping(int_subarg, string_subarg))
+                       {
+                               d_fprintf(stderr, "Could not create or modify "
+                                         "uid to sid mapping\n");
+                               goto done;
+                       }
+                       break;
+               case OPT_SET_GID_MAPPING:
+                       if (!parse_mapping_arg(string_arg, &int_subarg,
+                               &string_subarg) ||
+                           !wbinfo_set_gid_mapping(int_subarg, string_subarg))
+                       {
+                               d_fprintf(stderr, "Could not create or modify "
+                                         "gid to sid mapping\n");
+                               goto done;
+                       }
+                       break;
                case 't':
                        if (!wbinfo_check_secret()) {
                                d_fprintf(stderr, "Could not check secret\n");