]>
Commit | Line | Data |
---|---|---|
50f301a8 | 1 | /* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. |
51702635 UD |
2 | This file is part of the GNU C Library. |
3 | Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1997. | |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Library General Public License as | |
7 | published by the Free Software Foundation; either version 2 of the | |
8 | License, or (at your option) any later version. | |
9 | ||
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 | |
13 | Library General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Library General Public | |
16 | License along with the GNU C Library; see the file COPYING.LIB. If not, | |
17 | write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
18 | Boston, MA 02111-1307, USA. */ | |
19 | ||
20 | #include <string.h> | |
21 | #include <rpcsvc/nis.h> | |
91eee4dd | 22 | #include "nis_xdr.h" |
51702635 UD |
23 | #include "nis_intern.h" |
24 | ||
25 | nis_result * | |
a1129917 | 26 | nis_lookup (const_nis_name name, const unsigned int flags) |
51702635 | 27 | { |
e852e889 | 28 | nis_result *res = calloc (1, sizeof (nis_result)); |
51702635 UD |
29 | struct ns_request req; |
30 | nis_name *names; | |
31 | nis_error status; | |
e852e889 | 32 | int link_first_try = 0; |
51702635 | 33 | int count_links = 0; /* We will follow only 16 links in the deep */ |
2d7da676 UD |
34 | int done = 0; |
35 | int name_nr = 0; | |
36 | nis_name namebuf[2] = {NULL, NULL}; | |
51702635 | 37 | |
91eee4dd UD |
38 | if (res == NULL) |
39 | return NULL; | |
51702635 | 40 | |
e852e889 | 41 | if ((flags & EXPAND_NAME) && (name[strlen (name) - 1] != '.')) |
51702635 | 42 | { |
2d7da676 | 43 | names = nis_getnames (name); |
51702635 UD |
44 | if (names == NULL) |
45 | { | |
91eee4dd | 46 | NIS_RES_STATUS (res) = NIS_NAMEUNREACHABLE; |
51702635 UD |
47 | return res; |
48 | } | |
51702635 UD |
49 | } |
50 | else | |
51 | { | |
2d7da676 | 52 | names = namebuf; |
91eee4dd | 53 | names[0] = (nis_name)name; |
2d7da676 | 54 | } |
51702635 | 55 | |
2d7da676 UD |
56 | req.ns_name = names[0]; |
57 | while (!done) | |
58 | { | |
e852e889 UD |
59 | dir_binding bptr; |
60 | directory_obj *dir = NULL; | |
2d7da676 UD |
61 | req.ns_object.ns_object_len = 0; |
62 | req.ns_object.ns_object_val = NULL; | |
2d7da676 | 63 | |
e852e889 | 64 | status = __nisfind_server (req.ns_name, &dir); |
2d7da676 | 65 | if (status != NIS_SUCCESS) |
e852e889 UD |
66 | { |
67 | NIS_RES_STATUS (res) = status; | |
68 | return res; | |
69 | } | |
2d7da676 | 70 | |
e852e889 UD |
71 | status = __nisbind_create (&bptr, dir->do_servers.do_servers_val, |
72 | dir->do_servers.do_servers_len, flags); | |
73 | if (status != NIS_SUCCESS) | |
51702635 | 74 | { |
e852e889 UD |
75 | NIS_RES_STATUS (res) = status; |
76 | nis_free_directory (dir); | |
77 | return res; | |
78 | } | |
79 | ||
80 | while (__nisbind_connect (&bptr) != NIS_SUCCESS) | |
81 | { | |
82 | if (__nisbind_next (&bptr) != NIS_SUCCESS) | |
83 | { | |
84 | __nisbind_destroy (&bptr); | |
85 | nis_free_directory (dir); | |
86 | NIS_RES_STATUS (res) = NIS_NAMEUNREACHABLE; | |
87 | return res; | |
88 | } | |
89 | } | |
90 | ||
91 | do | |
92 | { | |
93 | static struct timeval RPCTIMEOUT = {10, 0}; | |
94 | enum clnt_stat result; | |
95 | ||
96 | again: | |
97 | result = clnt_call (bptr.clnt, NIS_LOOKUP, | |
98 | (xdrproc_t) _xdr_ns_request, | |
99 | (caddr_t) &req, (xdrproc_t) _xdr_nis_result, | |
100 | (caddr_t) res, RPCTIMEOUT); | |
101 | ||
102 | if (result != RPC_SUCCESS) | |
103 | status = NIS_RPCERROR; | |
104 | else | |
51702635 | 105 | { |
50f301a8 AS |
106 | status = NIS_SUCCESS; |
107 | ||
e852e889 | 108 | if (NIS_RES_STATUS (res) == NIS_SUCCESS) |
2d7da676 | 109 | { |
e852e889 UD |
110 | if (__type_of(NIS_RES_OBJECT (res)) == NIS_LINK_OBJ && |
111 | flags & FOLLOW_LINKS) /* We are following links */ | |
112 | { | |
113 | if (count_links) | |
114 | free (req.ns_name); | |
115 | /* if we hit the link limit, bail */ | |
116 | if (count_links > NIS_MAXLINKS) | |
117 | { | |
118 | NIS_RES_STATUS (res) = NIS_LINKNAMEERROR; | |
119 | break; | |
120 | } | |
121 | ++count_links; | |
122 | req.ns_name = | |
123 | strdup (NIS_RES_OBJECT (res)->LI_data.li_name); | |
32abdb71 UD |
124 | if (req.ns_name == NULL) |
125 | return NULL; | |
126 | ||
e852e889 UD |
127 | nis_freeresult (res); |
128 | res = calloc (1, sizeof (nis_result)); | |
129 | if (res == NULL) | |
2acd8fcf UD |
130 | { |
131 | __nisbind_destroy (&bptr); | |
132 | return NULL; | |
133 | } | |
32abdb71 | 134 | |
e852e889 UD |
135 | link_first_try = 1; /* Try at first the old binding */ |
136 | goto again; | |
137 | } | |
2d7da676 | 138 | } |
e852e889 UD |
139 | else |
140 | if ((NIS_RES_STATUS (res) == NIS_SYSTEMERROR) || | |
141 | (NIS_RES_STATUS (res) == NIS_NOSUCHNAME) || | |
142 | (NIS_RES_STATUS (res) == NIS_NOT_ME)) | |
143 | { | |
144 | if (link_first_try) | |
145 | { | |
146 | __nisbind_destroy (&bptr); | |
147 | nis_free_directory (dir); | |
148 | ||
149 | if (__nisfind_server (req.ns_name, &dir) != NIS_SUCCESS) | |
150 | return res; | |
151 | ||
152 | if (__nisbind_create (&bptr, | |
153 | dir->do_servers.do_servers_val, | |
154 | dir->do_servers.do_servers_len, | |
155 | flags) != NIS_SUCCESS) | |
156 | { | |
157 | nis_free_directory (dir); | |
158 | return res; | |
159 | } | |
160 | } | |
161 | else | |
162 | if (__nisbind_next (&bptr) != NIS_SUCCESS) | |
163 | break; /* No more servers to search */ | |
164 | ||
165 | while (__nisbind_connect (&bptr) != NIS_SUCCESS) | |
166 | { | |
167 | if (__nisbind_next (&bptr) != NIS_SUCCESS) | |
168 | { | |
169 | __nisbind_destroy (&bptr); | |
170 | nis_free_directory (dir); | |
171 | return res; | |
172 | } | |
173 | } | |
174 | goto again; | |
175 | } | |
176 | break; | |
51702635 | 177 | } |
e852e889 | 178 | link_first_try = 0; /* Set it back */ |
e852e889 UD |
179 | } |
180 | while ((flags & HARD_LOOKUP) && status == NIS_RPCERROR); | |
181 | ||
182 | __nisbind_destroy (&bptr); | |
183 | nis_free_directory (dir); | |
184 | ||
185 | if (status != NIS_SUCCESS) | |
186 | { | |
187 | NIS_RES_STATUS (res) = status; | |
188 | return res; | |
189 | } | |
190 | ||
191 | switch (NIS_RES_STATUS (res)) | |
192 | { | |
193 | case NIS_PARTIAL: | |
194 | case NIS_SUCCESS: | |
195 | case NIS_S_SUCCESS: | |
196 | case NIS_LINKNAMEERROR: /* We follow to max links */ | |
197 | case NIS_UNAVAIL: /* NIS+ is not installed, or all servers are down */ | |
3996f34b UD |
198 | ++done; |
199 | break; | |
2d7da676 UD |
200 | default: |
201 | /* Try the next domainname if we don't follow a link */ | |
202 | if (count_links) | |
51702635 | 203 | { |
2d7da676 | 204 | free (req.ns_name); |
91eee4dd | 205 | NIS_RES_STATUS (res) = NIS_LINKNAMEERROR; |
2d7da676 UD |
206 | ++done; |
207 | break; | |
51702635 | 208 | } |
2d7da676 UD |
209 | ++name_nr; |
210 | if (names[name_nr] == NULL) | |
211 | { | |
212 | ++done; | |
213 | break; | |
214 | } | |
215 | req.ns_name = names[name_nr]; | |
216 | break; | |
51702635 UD |
217 | } |
218 | } | |
219 | ||
2d7da676 UD |
220 | if (names != namebuf) |
221 | nis_freenames (names); | |
222 | ||
51702635 UD |
223 | return res; |
224 | } |