4 * Authentication procedures for mountd.
6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
33 static void auth_fixpath(char *path);
38 auth_init(char *exports)
49 static time_t last_modified = 0;
51 if (stat(_PATH_ETAB, &stb) < 0)
52 xlog(L_FATAL, "couldn't stat %s", _PATH_ETAB);
53 if (stb.st_mtime == last_modified)
55 last_modified = stb.st_mtime;
64 auth_authenticate_internal(char *what, struct sockaddr_in *caller,
65 char *path, struct hostent *hp,
66 enum auth_error *error)
68 struct in_addr addr = caller->sin_addr;
71 static nfs_export my_exp;
72 static nfs_client my_client;
76 /* return static nfs_export with details filled in */
77 if (my_client.m_naddr != 1 ||
78 my_client.m_addrlist[0].s_addr != caller->sin_addr.s_addr) {
80 my_client.m_naddr = 0;
81 my_client.m_addrlist[0] = caller->sin_addr;
82 n = client_compose(addr);
85 strcpy(my_client.m_hostname, *n?n:"DEFAULT");
87 my_client.m_naddr = 1;
90 my_exp.m_client = &my_client;
93 for (i = 0; !exp && i < MCL_MAXTYPES; i++)
94 for (exp = exportlist[i]; exp; exp = exp->m_next) {
95 if (!client_member(my_client.m_hostname, exp->m_client->m_hostname))
97 if (strcmp(path, exp->m_export.e_path))
101 *error = not_exported;
105 my_exp.m_export = exp->m_export;
109 if (!(exp = export_find(hp, path))) {
113 if (!exp->m_mayexport) {
114 *error = not_exported;
118 if (!(exp->m_export.e_flags & NFSEXP_INSECURE_PORT) &&
119 (ntohs(caller->sin_port) < IPPORT_RESERVED/2 ||
120 ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
121 *error = illegal_port;
132 auth_authenticate(char *what, struct sockaddr_in *caller, char *path)
134 nfs_export *exp = NULL;
135 char epath[MAXPATHLEN+1];
137 struct hostent *hp = NULL;
138 struct in_addr addr = caller->sin_addr;
139 enum auth_error error;
141 if (path [0] != '/') {
142 xlog(L_WARNING, "bad path in %s request from %s: \"%s\"",
143 what, inet_ntoa(addr), path);
147 strncpy(epath, path, sizeof (epath) - 1);
148 epath[sizeof (epath) - 1] = '\0';
149 auth_fixpath(epath);/* strip dup '/' etc */
151 hp = get_reliable_hostbyaddr((const char*)&caller->sin_addr, sizeof(struct in_addr),
154 hp = get_hostent((const char*)&caller->sin_addr, sizeof(struct in_addr),
158 /* Try the longest matching exported pathname. */
160 exp = auth_authenticate_internal(what, caller, epath,
162 if (exp || (error != not_exported && error != no_entry))
164 /* We have to treat the root, "/", specially. */
165 if (p == &epath[1]) break;
166 p = strrchr(epath, '/');
174 xlog(L_WARNING, "bad path in %s request from %s: \"%s\"",
175 what, inet_ntoa(addr), path);
179 xlog(L_WARNING, "%s request from unknown host %s for %s (%s)",
180 what, inet_ntoa(addr), path, epath);
184 xlog(L_WARNING, "refused %s request from %s for %s (%s): no export entry",
185 what, hp->h_name, path, epath);
189 xlog(L_WARNING, "refused %s request from %s for %s (%s): not exported",
190 what, hp->h_name, path, epath);
194 xlog(L_WARNING, "refused %s request from %s for %s (%s): illegal port %d",
195 what, hp->h_name, path, epath, ntohs(caller->sin_port));
199 xlog(L_WARNING, "refused %s request from %s (%s) for %s (%s): DNS forward lookup does't match with reverse",
200 what, inet_ntoa(addr), hp->h_name, path, epath);
204 xlog(L_WARNING, "refused %s request from %s (%s) for %s (%s): no DNS forward lookup",
205 what, inet_ntoa(addr), hp->h_name, path, epath);
209 xlog(L_NOTICE, "authenticated %s request from %s:%d for %s (%s)",
210 what, hp->h_name, ntohs(caller->sin_port), path, epath);
213 xlog(L_NOTICE, "%s request from %s:%d for %s (%s) gave %d",
214 what, hp->h_name, ntohs(caller->sin_port), path, epath, error);
224 * Remove duplicate and trailing '/' (Except for leading slash)
227 auth_fixpath(char *path)
231 for (sp = cp = path; *sp; sp++) {
232 if (*sp != '/' || sp[1] != '/')
235 while (cp > path+1 && cp[-1] == '/')