fprintf(shadow_logfd, "%s did not provide @find_subid_owners@\n", libname);
goto close_lib;
}
+ subid_nss->free= dlsym(h, "shadow_subid_free");
+ if (!subid_nss->free) {
+ // Fallback to default `free()` for backward compatibility.
+ subid_nss->free = free;
+ }
subid_nss->handle = h;
goto done;
*/
enum subid_status (*find_subid_owners)(unsigned long id, enum subid_type id_type, uid_t **uids, int *count);
+ /*
+ * nss_free: free a memory block allocated by a subid plugin.
+ *
+ * @ptr - a pointer to a memory block to deallocate
+ *
+ * Some routines of subid_nss_ops allocate memory which should be freed by
+ * caller after use. In order to deallocate that memory block, one should
+ * use this routine to release that memory. By default, this function
+ * pointer is set to free() for backward compatibility. However, it is
+ * strongly recommended to define this routine explicitly.
+ */
+ void (*free)(void *ptr);
+
/* The dlsym handle to close */
void *handle;
};
return ret;
}
+void free_subid_pointer(void *ptr) {
+ struct subid_nss_ops *h = get_subid_nss_handle();
+ if (h) {
+ h->free(ptr);
+ } else {
+ free(ptr);
+ }
+}
+
#else /* !ENABLE_SUBIDS */
extern int ISO_C_forbids_an_empty_translation_unit;
#endif /* !ENABLE_SUBIDS */
extern int sub_gid_add (const char *owner, gid_t start, unsigned long count);
extern int sub_gid_remove (const char *owner, gid_t start, unsigned long count);
extern uid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count);
+
+extern void free_subid_pointer(void *ptr);
+
#endif /* ENABLE_SUBIDS */
#endif
return true;
}
+void subid_free(void *ptr) {
+ free_subid_pointer(ptr);
+}
+
static
int get_subid_ranges(const char *owner, enum subid_type id_type, struct subid_range **ranges)
{
*/
bool subid_init(const char *progname, FILE *logfd);
+/*
+ * subid_free: free memory allocated in any subid_* function
+ *
+ * @ptr: Pointer to a memory block to release.
+ *
+ * Some functions like @subid_get_uid_ranges allocate memory internally. As
+ * soon as a result is no longer needed, it should be freed with this routine.
+ * Initially, default function `free()` was used. Thus for backward
+ * compatibility this function falls back to `free()` if a plugin does not
+ * explicitly specify routine to free allocated memory.
+ */
+void subid_free(void *ptr);
+
/*
* subid_get_uid_ranges: return a list of UID ranges for a user
*
printf("%d: %s %lu %lu\n", i, owner,
ranges[i].start, ranges[i].count);
}
- free(ranges);
+ subid_free(ranges);
return 0;
}