]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
winbind:varlink: Check memory allocation when creating the records
authorSamuel Cabrero <scabrero@samba.org>
Mon, 3 Feb 2025 13:15:07 +0000 (14:15 +0100)
committerAndreas Schneider <asn@cryptomilk.org>
Thu, 20 Feb 2025 08:07:32 +0000 (08:07 +0000)
Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source3/winbindd/winbindd_varlink.h
source3/winbindd/winbindd_varlink_getgrouprecord.c
source3/winbindd/winbindd_varlink_getmemberships.c
source3/winbindd/winbindd_varlink_getuserrecord.c

index ae30928f8b2fecaf637db9f631c9b26b7919312b..f34889ba9334a1b55e931b8880a5a48593bd8b6d 100644 (file)
@@ -39,6 +39,13 @@ extern bool vl_active;
 #define WB_VL_REPLY_ERROR_ENUMERATION_NOT_SUPPORTED \
        "io.systemd.UserDatabase.EnumerationNotSupported"
 
+#define WB_VL_ERR_CHECK_GOTO(p, l) do { \
+       int rc = (p); \
+       if (rc < 0) { \
+               DBG_ERR("'"#p"' failed: %s\n", varlink_error_string(rc)); \
+               goto l; \
+       }} while (0)
+
 NTSTATUS wb_vl_fake_cli_state(VarlinkCall *call,
                              const char *service,
                              struct winbindd_cli_state *cli);
index 63e2ddd435800c75040dad8353abf7e3e7155756..794a3c57ba60b4d088beb8911763e7ea9422aba5 100644 (file)
@@ -40,30 +40,52 @@ static void group_record_reply(VarlinkCall *call,
                                            "service name",
                                            WB_VL_SERVICE_NAME);
 
-       varlink_object_new(&record);
-       varlink_object_set_string(record, "service", service_name);
-       varlink_object_set_string(record, "groupName", gr->gr_name);
-       varlink_object_set_int(record, "gid", gr->gr_gid);
+       WB_VL_ERR_CHECK_GOTO(varlink_object_new(&record), err_free_record);
+       WB_VL_ERR_CHECK_GOTO(varlink_object_set_string(
+               record, "service", service_name), err_free_record);
+       WB_VL_ERR_CHECK_GOTO(varlink_object_set_string(
+               record, "groupName", gr->gr_name), err_free_record);
+       WB_VL_ERR_CHECK_GOTO(varlink_object_set_int(
+               record, "gid", gr->gr_gid), err_free_record);
 
        if (gr->num_gr_mem > 0 && gr_members != NULL) {
-               varlink_array_new(&members);
+               WB_VL_ERR_CHECK_GOTO(varlink_array_new(
+                       &members), err_free_members);
                for ((name = strtok_r(gr_members, ",", &p)), i = 0;
                     name != NULL;
                     name = strtok_r(NULL, ",", &p), i++) {
                        if (i == gr->num_gr_mem) {
                                break;
                        }
-                       varlink_array_append_string(members, name);
+                       WB_VL_ERR_CHECK_GOTO(varlink_array_append_string(
+                               members, name), err_free_members);
                }
-               varlink_object_set_array(record, "members", members);
+               WB_VL_ERR_CHECK_GOTO(varlink_object_set_array(
+                       record, "members", members), err_free_members);
        }
 
-       varlink_object_new(&out);
-       varlink_object_set_object(out, "record", record);
-       varlink_object_set_bool(out, "incomplete", false);
+       WB_VL_ERR_CHECK_GOTO(varlink_object_new(&out), err_free_out);
+       WB_VL_ERR_CHECK_GOTO(varlink_object_set_bool(
+               out, "incomplete", false), err_free_out);
+       WB_VL_ERR_CHECK_GOTO(varlink_object_set_object(
+               out, "record", record), err_free_out);
 
        varlink_call_reply(call, out, continues ? VARLINK_REPLY_CONTINUES : 0);
        varlink_object_unref(out);
+       return;
+
+err_free_members:
+       if (members != NULL) {
+               varlink_array_unref(members);
+       }
+err_free_out:
+       if (out != NULL) {
+               varlink_object_unref(out);
+       }
+err_free_record:
+       if (record != NULL) {
+               varlink_object_unref(record);
+       }
 }
 
 /******************************************************************************
index 780e99f4f2acaa8f6319b5ee18a3d2ee5aa39d3b..14c91fa344bba65ee460fa6ff9fe7ee6e8169906 100644 (file)
@@ -29,12 +29,17 @@ static void membership_reply(VarlinkCall *call,
 {
        VarlinkObject *out = NULL;
 
-       varlink_object_new(&out);
-       varlink_object_set_string(out, "userName", username);
-       varlink_object_set_string(out, "groupName", groupname);
-
+       WB_VL_ERR_CHECK_GOTO(varlink_object_new(&out), err_free_out);
+       WB_VL_ERR_CHECK_GOTO(varlink_object_set_string(
+               out, "userName", username), err_free_out);
+       WB_VL_ERR_CHECK_GOTO(varlink_object_set_string(
+               out, "groupName", groupname), err_free_out);
        varlink_call_reply(call, out, continues ? VARLINK_REPLY_CONTINUES : 0);
-       varlink_object_unref(out);
+
+err_free_out:
+       if (out != NULL) {
+               varlink_object_unref(out);
+       }
 }
 
 static void member_list_reply(VarlinkCall *call,
index d96d8f47fb5c3a212b164f25ddd34b6a35448f31..566cfba3cbe567e5aa5097fd4c68e1dceab98d98 100644 (file)
@@ -34,27 +34,39 @@ user_record_reply(VarlinkCall *call, struct winbindd_pw *pw, bool continues)
                                            "service name",
                                            WB_VL_SERVICE_NAME);
 
-       varlink_object_new(&record);
-       varlink_object_set_string(record, "service", service_name);
-       varlink_object_set_string(record, "userName", pw->pw_name);
-       varlink_object_set_int(record, "uid", pw->pw_uid);
-       varlink_object_set_int(record, "gid", pw->pw_gid);
+       WB_VL_ERR_CHECK_GOTO(varlink_object_new(&record), err_free_record);
+       WB_VL_ERR_CHECK_GOTO(varlink_object_set_string(record, "service", service_name), err_free_record);
+       WB_VL_ERR_CHECK_GOTO(varlink_object_set_string(record, "userName", pw->pw_name), err_free_record);
+       WB_VL_ERR_CHECK_GOTO(varlink_object_set_int(record, "uid", pw->pw_uid), err_free_record);
+       WB_VL_ERR_CHECK_GOTO(varlink_object_set_int(record, "gid", pw->pw_gid), err_free_record);
        if (strlen(pw->pw_dir) > 0) {
-               varlink_object_set_string(record, "homeDirectory", pw->pw_dir);
+               WB_VL_ERR_CHECK_GOTO(varlink_object_set_string(
+                       record, "homeDirectory", pw->pw_dir), err_free_record);
        }
        if (strlen(pw->pw_shell) > 0) {
-               varlink_object_set_string(record, "shell", pw->pw_shell);
+               WB_VL_ERR_CHECK_GOTO(varlink_object_set_string(
+                       record, "shell", pw->pw_shell), err_free_record);
        }
        if (strlen(pw->pw_gecos) > 0) {
-               varlink_object_set_string(record, "realName", pw->pw_gecos);
+               WB_VL_ERR_CHECK_GOTO(varlink_object_set_string(
+                       record, "realName", pw->pw_gecos), err_free_record);
        }
 
-       varlink_object_new(&out);
-       varlink_object_set_object(out, "record", record);
-       varlink_object_set_bool(out, "incomplete", false);
+       WB_VL_ERR_CHECK_GOTO(varlink_object_new(&out), err_free_out);
+       WB_VL_ERR_CHECK_GOTO(varlink_object_set_bool(out, "incomplete", false), err_free_out);
+       WB_VL_ERR_CHECK_GOTO(varlink_object_set_object(out, "record", record), err_free_out);
 
        varlink_call_reply(call, out, continues ? VARLINK_REPLY_CONTINUES : 0);
        varlink_object_unref(out);
+       return;
+err_free_out:
+       if (out != NULL) {
+               varlink_object_unref(out);
+       }
+err_free_record:
+       if (record != NULL) {
+               varlink_object_unref(record);
+       }
 }
 
 /******************************************************************************