2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
17 #include <afs/pthread_glock.h>
18 #include <sys/types.h>
25 #include <netinet/in.h>
29 #include <stdlib.h> /* for realpath() */
37 #include <afs/afsutil.h>
38 #include <afs/fileutil.h>
40 #ifdef AFS_ATHENA_STDENV
45 #include "cellconfig.h"
47 #include "afs/audit.h"
51 afsconf_CheckAuth(register struct afsconf_dir *adir,
52 register struct rx_call *acall)
55 return ((afsconf_SuperUser(adir, acall, NULL) == 0) ? 10029 : 0);
58 #endif /* !defined(UKERNEL) */
61 GetNoAuthFlag(struct afsconf_dir *adir)
63 if (access(AFSDIR_SERVER_NOAUTH_FILEPATH, 0) == 0) {
64 osi_audit(NoAuthEvent, 0, AUD_END); /* some random server is running noauth */
65 return 1; /* if /usr/afs/local/NoAuth file exists, allow access */
72 afsconf_GetNoAuthFlag(struct afsconf_dir *adir)
77 rc = GetNoAuthFlag(adir);
83 afsconf_SetNoAuthFlag(struct afsconf_dir *adir, int aflag)
85 register afs_int32 code;
89 /* turn off noauth flag */
90 code = (unlink(AFSDIR_SERVER_NOAUTH_FILEPATH) ? errno : 0);
91 osi_audit(NoAuthDisableEvent, code, AUD_END);
93 /* try to create file */
95 open(AFSDIR_SERVER_NOAUTH_FILEPATH, O_CREAT | O_TRUNC | O_RDWR,
99 osi_audit(NoAuthEnableEvent, 0, AUD_END);
101 osi_audit(NoAuthEnableEvent, errno, AUD_END);
106 /* deletes a user from the UserList file */
108 afsconf_DeleteUser(struct afsconf_dir *adir, register char *auser)
119 register afs_int32 code;
122 strcompose(tbuffer, sizeof tbuffer, adir->name, "/",
123 AFSDIR_ULIST_FILE, NULL);
127 * We attempt to fully resolve this pathname, so that the rename
128 * of the temporary file will work even if UserList is a symlink
129 * into a different filesystem.
131 char resolved_path[1024];
133 if (realpath(tbuffer, resolved_path)) {
134 strcpy(tbuffer, resolved_path);
137 #endif /* AFS_NT40_ENV */
138 tf = fopen(tbuffer, "r");
143 code = stat(tbuffer, &tstat);
148 strcpy(nbuffer, tbuffer);
149 strcat(nbuffer, ".NXX");
150 nf = fopen(nbuffer, "w+");
159 /* check for our user id */
160 tp = fgets(nbuffer, sizeof(nbuffer), tf);
163 code = sscanf(nbuffer, "%64s", tname);
164 if (code == 1 && strcmp(tname, auser) == 0) {
165 /* found the guy, don't copy to output file */
168 /* otherwise copy original line to output */
169 fprintf(nf, "%s", nbuffer);
175 if (fclose(nf) == EOF)
177 strcpy(nbuffer, tbuffer);
178 strcat(nbuffer, ".NXX"); /* generate new file name again */
181 flag = renamefile(nbuffer, tbuffer);
183 flag = chmod(tbuffer, tstat.st_mode);
187 /* finally, decide what to return to the caller */
190 return EIO; /* something mysterious went wrong */
192 return ENOENT; /* entry wasn't found, no changes made */
193 return 0; /* everything was fine */
196 /* returns nth super user from the UserList file */
198 afsconf_GetNthUser(struct afsconf_dir *adir, afs_int32 an, char *abuffer,
199 afs_int32 abufferLen)
206 register afs_int32 code;
209 strcompose(tbuffer, sizeof tbuffer, adir->name, "/",
210 AFSDIR_ULIST_FILE, NULL);
211 tf = fopen(tbuffer, "r");
218 /* check for our user id */
219 tp = fgets(tbuffer, sizeof(tbuffer), tf);
222 code = sscanf(tbuffer, "%64s", tname);
223 if (code == 1 && an-- == 0) {
229 strcpy(abuffer, tname);
235 /* returns true iff user is in the UserList file */
237 FindUser(struct afsconf_dir *adir, register char *auser)
243 register afs_int32 code;
246 strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE,
248 bp = BufioOpen(tbuffer, O_RDONLY, 0);
253 /* check for our user id */
254 rc = BufioGets(bp, tbuffer, sizeof(tbuffer));
257 code = sscanf(tbuffer, "%64s", tname);
258 if (code == 1 && strcmp(tname, auser) == 0) {
267 /* add a user to the user list, checking for duplicates */
269 afsconf_AddUser(struct afsconf_dir *adir, char *aname)
272 register afs_int32 code;
276 if (FindUser(adir, aname)) {
278 return EEXIST; /* already in the list */
281 strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE,
283 tf = fopen(tbuffer, "a+");
288 fprintf(tf, "%s\n", aname);
298 /* special CompFindUser routine that builds up a princ and then
299 calls finduser on it. If found, returns char * to user string,
300 otherwise returns NULL. The resulting string should be immediately
301 copied to other storage prior to release of mutex. */
303 CompFindUser(struct afsconf_dir *adir, char *name, char *sep, char *inst,
306 static char fullname[MAXKTCNAMELEN + MAXKTCNAMELEN + MAXKTCREALMLEN + 3];
308 /* always must have name */
309 if (!name || !name[0]) {
312 strcpy(fullname, name);
314 /* might have instance */
315 if (inst && inst[0]) {
316 if (!sep || !sep[0]) {
320 strcat(fullname, sep);
321 strcat(fullname, inst);
324 /* might have realm */
325 if (realm && realm[0]) {
326 strcat(fullname, "@");
327 strcat(fullname, realm);
330 if (FindUser(adir, fullname)) {
338 /* make sure user authenticated on rx call acall is in list of valid
339 users. Copy the "real name" of the authenticated user into namep
340 if a pointer is passed.
343 afsconf_SuperUser(struct afsconf_dir *adir, struct rx_call *acall, char *namep)
345 register struct rx_connection *tconn;
346 register afs_int32 code;
355 if (afsconf_GetNoAuthFlag(adir)) {
357 strcpy(namep, "<NoAuth>");
362 tconn = rx_ConnectionOf(acall);
363 code = rx_SecurityClassOf(tconn);
366 return 0; /* not authenticated at all, answer is no */
367 } else if (code == 1) {
370 return 0; /* not supported any longer */
371 } else if (code == 2) {
372 char tname[MAXKTCNAMELEN]; /* authentication from ticket */
373 char tinst[MAXKTCNAMELEN];
374 char tcell[MAXKTCREALMLEN];
375 char tcell_l[MAXKTCREALMLEN];
378 /* keep track of which one actually authorized request */
379 char uname[MAXKTCNAMELEN + MAXKTCNAMELEN + MAXKTCREALMLEN + 3];
382 static char lcell[MAXCELLCHARS] = "";
383 static char lrealms[AFS_NUM_LREALMS][AFS_REALM_SZ];
384 static int num_lrealms = -1;
385 int lrealm_match = 0, i;
387 /* get auth details from server connection */
389 rxkad_GetServerInfo(acall->conn, NULL, &exp, tname, tinst, tcell,
393 return 0; /* bogus connection/other error */
396 /* don't bother checking anything else if tix have expired */
397 #ifdef AFS_PTHREAD_ENV
398 if (exp < clock_Sec()) {
400 if (exp < FT_ApproxTime()) {
403 return 0; /* expired tix */
406 /* generate lowercased version of cell name */
407 strcpy(tcell_l, tcell);
410 *tmp = tolower(*tmp);
414 /* determine local cell name. It's static, so will only get
415 * calculated the first time through */
417 afsconf_GetLocalCell(adir, lcell, sizeof(lcell));
419 /* if running a krb environment, also get the local realm */
420 /* note - this assumes AFS_REALM_SZ <= MAXCELLCHARS */
421 /* just set it to lcell if it fails */
422 if (num_lrealms == -1) {
423 for (i=0; i<AFS_NUM_LREALMS; i++) {
424 if (afs_krb_get_lrealm(lrealms[i], i) != 0 /*KSUCCESS*/)
429 strncpy(lrealms[0], lcell, AFS_REALM_SZ);
436 /* See if the ticket cell matches one of the local realms */
438 for ( i=0;i<num_lrealms;i++ ) {
439 if (!strcasecmp(lrealms[i], tcell)) {
445 /* If yes, then make sure that the name is not present in
446 * an exclusion list */
449 snprintf(uname,sizeof(uname),"%s.%s@%s",tname,tinst,tcell);
451 snprintf(uname,sizeof(uname),"%s@%s",tname,tcell);
453 if (afs_krb_exclusion(uname))
457 /* start with no uname and no authorization */
461 /* localauth special case */
462 if (strlen(tinst) == 0 && strlen(tcell) == 0
463 && !strcmp(tname, AUTH_SUPERUSER)) {
464 strcpy(uname, "<LocalAuth>");
467 /* cell of connection matches local cell or one of the realms */
468 } else if (!strcasecmp(tcell, lcell) || lrealm_match) {
469 if ((tmp = CompFindUser(adir, tname, ".", tinst, NULL))) {
473 } else if ((tmp = CompFindUser(adir, tname, "/", tinst, NULL))) {
478 /* cell of conn doesn't match local cell or realm */
480 if ((tmp = CompFindUser(adir, tname, ".", tinst, tcell))) {
484 } else if ((tmp = CompFindUser(adir, tname, "/", tinst, tcell))) {
488 } else if ((tmp = CompFindUser(adir, tname, ".", tinst, tcell_l))) {
492 } else if ((tmp = CompFindUser(adir, tname, "/", tinst, tcell_l))) {
500 strcpy(namep, uname);
503 } else { /* some other auth type */
505 return 0; /* mysterious, just say no */