]> git.ipfire.org Git - thirdparty/glibc.git/blame - nss/nsswitch.c
nsswitch: handle missing actions properly
[thirdparty/glibc.git] / nss / nsswitch.c
CommitLineData
d614a753 1/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
2303f5fd
UD
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
5f0e6fc7 4
2303f5fd 5 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
5f0e6fc7 9
2303f5fd
UD
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 13 Lesser General Public License for more details.
5f0e6fc7 14
41bdb6e2 15 You should have received a copy of the GNU Lesser General Public
59ba27a6 16 License along with the GNU C Library; if not, see
5a82c748 17 <https://www.gnu.org/licenses/>. */
5f0e6fc7
RM
18
19#include <ctype.h>
20#include <dlfcn.h>
a8874ead 21#include <errno.h>
5f0e6fc7 22#include <netdb.h>
ec999b8e 23#include <libc-lock.h>
5f0e6fc7
RM
24#include <search.h>
25#include <stdio.h>
2706ee38 26#include <stdio_ext.h>
5f0e6fc7
RM
27#include <stdlib.h>
28#include <string.h>
5107cf1d 29
7f28638c
AJ
30#include <aliases.h>
31#include <grp.h>
32#include <netinet/ether.h>
33#include <pwd.h>
34#include <shadow.h>
f8847d83 35#include <unistd.h>
7f28638c 36
b5567b2a 37#if !defined DO_STATIC_NSS || defined SHARED
5107cf1d
UD
38# include <gnu/lib-names.h>
39#endif
5f0e6fc7
RM
40
41#include "nsswitch.h"
ef4d5b32 42#include "../nscd/nscd_proto.h"
319b9ad4 43#include <sysdep.h>
a1a78204
SE
44#include <config.h>
45
a8874ead
UD
46/* Declare external database variables. */
47#define DEFINE_DATABASE(name) \
f8847d83 48 nss_action_list __nss_##name##_database attribute_hidden; \
a8874ead
UD
49 weak_extern (__nss_##name##_database)
50#include "databases.def"
51#undef DEFINE_DATABASE
52
f8847d83 53
a8874ead 54#undef DEFINE_DATABASE
f8847d83
DD
55#define DEFINE_DATABASE(name) #name,
56static const char * database_names[] = {
57#include "databases.def"
58 NULL
a8874ead
UD
59};
60
1dbbb1ec 61#ifdef USE_NSCD
c3e2f19b
UD
62/* Flags whether custom rules for database is set. */
63bool __nss_database_custom[NSS_DBSIDX_max];
1dbbb1ec 64#endif
c3e2f19b 65
a8874ead 66
f8847d83 67/*__libc_lock_define_initialized (static, lock)*/
319b9ad4 68
5f0e6fc7
RM
69/* -1 == database not found
70 0 == database entry pointer stored */
71int
a9368c34 72__nss_database_lookup2 (const char *database, const char *alternate_name,
f8847d83 73 const char *defconfig, nss_action_list *ni)
5f0e6fc7 74{
f8847d83 75 int database_id;
bba7bb78 76
f8847d83
DD
77 for (database_id = 0; database_names[database_id]; database_id++)
78 if (strcmp (database_names[database_id], database) == 0)
79 break;
a8874ead 80
f8847d83
DD
81 if (database_names[database_id] == NULL)
82 return -1;
5f0e6fc7 83
d2e929a9
DD
84 /* If *NI is NULL, the database was not mentioned in nsswitch.conf.
85 If *NI is not NULL, but *NI->module is NULL, the database was in
86 nsswitch.conf but listed no actions. We test for the former. */
87 if (__nss_database_get (database_id, ni) && *ni != NULL)
5f0e6fc7 88 {
f8847d83
DD
89 /* Success. */
90 return 0;
5f0e6fc7 91 }
f8847d83 92 else
d44638b0 93 {
f8847d83
DD
94 /* Failure. */
95 return -1;
d44638b0 96 }
5f0e6fc7 97}
a9368c34 98libc_hidden_def (__nss_database_lookup2)
5f0e6fc7
RM
99
100
101/* -1 == not found
4317f9e1 102 0 == function found
14ea22e9 103 1 == finished */
5f0e6fc7 104int
f8847d83 105__nss_lookup (nss_action_list *ni, const char *fct_name, const char *fct2_name,
384ca551 106 void **fctp)
5f0e6fc7 107{
899d423e 108 *fctp = __nss_lookup_function (*ni, fct_name);
384ca551 109 if (*fctp == NULL && fct2_name != NULL)
0dc6c5e4 110 *fctp = __nss_lookup_function (*ni, fct2_name);
5f0e6fc7
RM
111
112 while (*fctp == NULL
113 && nss_next_action (*ni, NSS_STATUS_UNAVAIL) == NSS_ACTION_CONTINUE
f8847d83 114 && (*ni)[1].module != NULL)
5f0e6fc7 115 {
f8847d83 116 ++(*ni);
5f0e6fc7 117
899d423e 118 *fctp = __nss_lookup_function (*ni, fct_name);
384ca551 119 if (*fctp == NULL && fct2_name != NULL)
0dc6c5e4 120 *fctp = __nss_lookup_function (*ni, fct2_name);
5f0e6fc7
RM
121 }
122
f8847d83 123 return *fctp != NULL ? 0 : (*ni)[1].module == NULL ? 1 : -1;
5f0e6fc7 124}
684ae515 125libc_hidden_def (__nss_lookup)
5f0e6fc7
RM
126
127
128/* -1 == not found
129 0 == adjusted for next function
130 1 == finished */
131int
f8847d83 132__nss_next2 (nss_action_list *ni, const char *fct_name, const char *fct2_name,
384ca551 133 void **fctp, int status, int all_values)
5f0e6fc7
RM
134{
135 if (all_values)
136 {
137 if (nss_next_action (*ni, NSS_STATUS_TRYAGAIN) == NSS_ACTION_RETURN
138 && nss_next_action (*ni, NSS_STATUS_UNAVAIL) == NSS_ACTION_RETURN
139 && nss_next_action (*ni, NSS_STATUS_NOTFOUND) == NSS_ACTION_RETURN
140 && nss_next_action (*ni, NSS_STATUS_SUCCESS) == NSS_ACTION_RETURN)
141 return 1;
142 }
143 else
144 {
145 /* This is really only for debugging. */
384ca551
UD
146 if (__builtin_expect (NSS_STATUS_TRYAGAIN > status
147 || status > NSS_STATUS_RETURN, 0))
a6e8926f 148 __libc_fatal ("Illegal status in __nss_next.\n");
5f0e6fc7
RM
149
150 if (nss_next_action (*ni, status) == NSS_ACTION_RETURN)
151 return 1;
152 }
153
f8847d83 154 if ((*ni)[1].module == NULL)
5f0e6fc7
RM
155 return -1;
156
157 do
158 {
f8847d83 159 ++(*ni);
5f0e6fc7 160
899d423e 161 *fctp = __nss_lookup_function (*ni, fct_name);
384ca551
UD
162 if (*fctp == NULL && fct2_name != NULL)
163 *fctp = __nss_lookup_function (*ni, fct2_name);
5f0e6fc7
RM
164 }
165 while (*fctp == NULL
166 && nss_next_action (*ni, NSS_STATUS_UNAVAIL) == NSS_ACTION_CONTINUE
f8847d83 167 && (*ni)[1].module != NULL);
5f0e6fc7
RM
168
169 return *fctp != NULL ? 0 : -1;
170}
384ca551
UD
171libc_hidden_def (__nss_next2)
172
899d423e 173void *
f8847d83 174__nss_lookup_function (nss_action_list ni, const char *fct_name)
5f0e6fc7 175{
f8847d83 176 if (ni->module == NULL)
5f0e6fc7 177 return NULL;
f8847d83 178 return __nss_module_get_function (ni->module, fct_name);
d60d215c 179}
f8847d83 180libc_hidden_def (__nss_lookup_function)