4 * Authentication procedures for mountd.
6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
14 #include <netinet/in.h>
15 #include <arpa/inet.h>
34 static void auth_fixpath(char *path);
35 static char *export_file = NULL;
36 static nfs_export my_exp;
37 static nfs_client my_client;
42 auth_init(char *exports)
45 export_file = exports;
54 static ino_t last_inode;
56 static unsigned int counter;
59 if ((fd = open(_PATH_ETAB, O_RDONLY)) < 0) {
60 xlog(L_FATAL, "couldn't open %s", _PATH_ETAB);
61 } else if (fstat(fd, &stb) < 0) {
62 xlog(L_FATAL, "couldn't stat %s", _PATH_ETAB);
63 } else if (stb.st_ino == last_inode) {
69 last_inode = stb.st_ino;
73 memset(&my_client, 0, sizeof(my_client));
81 auth_authenticate_internal(char *what, struct sockaddr_in *caller,
82 char *path, struct hostent *hp,
83 enum auth_error *error)
89 /* return static nfs_export with details filled in */
91 my_client.m_addrlist[0] = caller->sin_addr;
92 n = client_compose(hp);
93 *error = unknown_host;
96 free(my_client.m_hostname);
98 my_client.m_hostname = n;
101 my_client.m_hostname = xstrdup("DEFAULT");
103 my_client.m_naddr = 1;
104 my_exp.m_client = &my_client;
107 for (i = 0; !exp && i < MCL_MAXTYPES; i++)
108 for (exp = exportlist[i]; exp; exp = exp->m_next) {
109 if (!client_member(my_client.m_hostname, exp->m_client->m_hostname))
111 if (strcmp(path, exp->m_export.e_path))
115 *error = not_exported;
119 my_exp.m_export = exp->m_export;
123 if (!(exp = export_find(hp, path))) {
127 if (!exp->m_mayexport) {
128 *error = not_exported;
132 if (!(exp->m_export.e_flags & NFSEXP_INSECURE_PORT) &&
133 (ntohs(caller->sin_port) < IPPORT_RESERVED/2 ||
134 ntohs(caller->sin_port) >= IPPORT_RESERVED)) {
135 *error = illegal_port;
144 auth_authenticate(char *what, struct sockaddr_in *caller, char *path)
146 nfs_export *exp = NULL;
147 char epath[MAXPATHLEN+1];
149 struct hostent *hp = NULL;
150 struct in_addr addr = caller->sin_addr;
151 enum auth_error error;
153 if (path [0] != '/') {
154 xlog(L_WARNING, "bad path in %s request from %s: \"%s\"",
155 what, inet_ntoa(addr), path);
159 strncpy(epath, path, sizeof (epath) - 1);
160 epath[sizeof (epath) - 1] = '\0';
161 auth_fixpath(epath); /* strip duplicate '/' etc */
163 hp = client_resolve(caller->sin_addr);
167 /* Try the longest matching exported pathname. */
169 exp = auth_authenticate_internal(what, caller, epath,
171 if (exp || (error != not_exported && error != no_entry))
173 /* We have to treat the root, "/", specially. */
174 if (p == &epath[1]) break;
175 p = strrchr(epath, '/');
182 xlog(L_WARNING, "bad path in %s request from %s: \"%s\"",
183 what, inet_ntoa(addr), path);
187 xlog(L_WARNING, "%s request from unknown host %s for %s (%s)",
188 what, inet_ntoa(addr), path, epath);
192 xlog(L_WARNING, "refused %s request from %s for %s (%s): no export entry",
193 what, hp->h_name, path, epath);
197 xlog(L_WARNING, "refused %s request from %s for %s (%s): not exported",
198 what, hp->h_name, path, epath);
202 xlog(L_WARNING, "refused %s request from %s for %s (%s): illegal port %d",
203 what, hp->h_name, path, epath, ntohs(caller->sin_port));
207 xlog(L_NOTICE, "authenticated %s request from %s:%d for %s (%s)",
208 what, hp->h_name, ntohs(caller->sin_port), path, epath);
211 xlog(L_NOTICE, "%s request from %s:%d for %s (%s) gave %d",
212 what, hp->h_name, ntohs(caller->sin_port), path, epath, error);
222 auth_fixpath(char *path)
226 for (sp = cp = path; *sp; sp++) {
227 if (*sp != '/' || sp[1] != '/')
230 while (cp > path+1 && cp[-1] == '/')