115 lines
3.2 KiB
Diff
115 lines
3.2 KiB
Diff
diff --git a/nss/nsswitch.c b/nss/nsswitch.c
|
|
index 3c48b4b85e..0d823e7ad2 100644
|
|
--- a/nss/nsswitch.c
|
|
+++ b/nss/nsswitch.c
|
|
@@ -337,6 +337,8 @@ known_compare (const void *p1, const void *p2)
|
|
static int
|
|
nss_load_library (service_user *ni)
|
|
{
|
|
+ char *ld_library_path;
|
|
+
|
|
if (ni->library == NULL)
|
|
{
|
|
/* This service has not yet been used. Fetch the service
|
|
@@ -366,6 +368,19 @@ nss_load_library (service_user *ni)
|
|
".so"),
|
|
__nss_shlib_revision);
|
|
|
|
+ if (ni->path != NULL)
|
|
+ {
|
|
+ /* Construct new LD_LIBRARY_PATH. */
|
|
+ ld_library_path = malloc (strlen (getenv ("LD_LIBRARY_PATH"))
|
|
+ + strlen (ni->path)
|
|
+ + 1);
|
|
+ __stpcpy (__stpcpy (__stpcpy (ld_library_path,
|
|
+ ni->path),
|
|
+ ":"),
|
|
+ getenv ("LD_LIBRARY_PATH"));
|
|
+ setenv ("LD_LIBRARY_PATH", ld_library_path, 1);
|
|
+ }
|
|
+
|
|
ni->library->lib_handle = __libc_dlopen (shlib_name);
|
|
if (ni->library->lib_handle == NULL)
|
|
{
|
|
@@ -622,6 +637,7 @@ nss_parse_service_list (const char *line)
|
|
{
|
|
service_user *new_service;
|
|
const char *name;
|
|
+ const char *path;
|
|
|
|
while (isspace (line[0]))
|
|
++line;
|
|
@@ -631,14 +647,14 @@ nss_parse_service_list (const char *line)
|
|
|
|
/* Read <source> identifier. */
|
|
name = line;
|
|
- while (line[0] != '\0' && !isspace (line[0]) && line[0] != '[')
|
|
+ while (line[0] != '\0' && !isspace (line[0]) && line[0] != '['
|
|
+ && line[0] != ':')
|
|
++line;
|
|
if (name == line)
|
|
return result;
|
|
|
|
-
|
|
new_service = (service_user *) malloc (sizeof (service_user)
|
|
- + (line - name + 1));
|
|
+ + line - name + 1);
|
|
if (new_service == NULL)
|
|
return result;
|
|
|
|
@@ -652,8 +668,22 @@ nss_parse_service_list (const char *line)
|
|
new_service->actions[2 + NSS_STATUS_RETURN] = NSS_ACTION_RETURN;
|
|
new_service->library = NULL;
|
|
new_service->known = NULL;
|
|
+ new_service->path = NULL;
|
|
new_service->next = NULL;
|
|
|
|
+ if (line[0] == ':')
|
|
+ {
|
|
+ /* Read path of the shared object */
|
|
+ ++line;
|
|
+ path = line;
|
|
+ while (line[0] != '\0' && !isspace (line[0]) && line[0] != '[')
|
|
+ ++line;
|
|
+ if (name == line)
|
|
+ return result;
|
|
+ new_service->path = (char *) malloc (line - path + 1);
|
|
+ *((char *) __mempcpy (new_service->path, path, line - path)) = '\0';
|
|
+ }
|
|
+
|
|
while (isspace (line[0]))
|
|
++line;
|
|
|
|
@@ -756,6 +786,8 @@ nss_parse_service_list (const char *line)
|
|
continue;
|
|
|
|
finish:
|
|
+ if (new_service->path != NULL)
|
|
+ free (new_service->path);
|
|
free (new_service);
|
|
return result;
|
|
}
|
|
@@ -884,6 +916,9 @@ free_database_entries (name_database_entry *entry)
|
|
if (service->known != NULL)
|
|
__tdestroy (service->known, free);
|
|
|
|
+ if (service->path != NULL)
|
|
+ free (service->path);
|
|
+
|
|
service = service->next;
|
|
free (olds);
|
|
}
|
|
diff --git a/nss/nsswitch.h b/nss/nsswitch.h
|
|
index 63573b9ebc..e31dba8358 100644
|
|
--- a/nss/nsswitch.h
|
|
+++ b/nss/nsswitch.h
|
|
@@ -68,6 +68,8 @@ typedef struct service_user
|
|
service_library *library;
|
|
/* Collection of known functions. */
|
|
void *known;
|
|
+ /* Path of the shared object file (will be prepended to LD_LIBRARY_PATH) */
|
|
+ char *path;
|
|
/* Name of the service (`files', `dns', `nis', ...). */
|
|
char name[0];
|
|
} service_user;
|