* directory or online at http://www.openafs.org/dl/license10.html
*/
-#include <afs/param.h>
#include <afsconfig.h>
+#include <afs/param.h>
-RCSID("$Header$");
+RCSID
+ ("$Header$");
#include <afs/stds.h>
#include <afs/pthread_glock.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <netdb.h>
+#include <unistd.h>
#endif
#include <sys/stat.h>
-#include <stdlib.h> /* for realpath() */
+#include <stdlib.h> /* for realpath() */
#include <errno.h>
#include <string.h>
#include <ctype.h>
-
+
#include <rx/xdr.h>
#include <rx/rx.h>
#include <stdio.h>
#include "keys.h"
#include "afs/audit.h"
-afs_int32 afsconf_SuperUser();
-
#if !defined(UKERNEL)
-int afsconf_CheckAuth(adir, acall)
-register struct rx_call *acall;
-register struct afsconf_dir *adir; {
- LOCK_GLOBAL_MUTEX
- return ((afsconf_SuperUser(adir, acall, (char *)0) == 0)? 10029 : 0);
- UNLOCK_GLOBAL_MUTEX
+int
+afsconf_CheckAuth(void *arock, struct rx_call *acall)
+{
+ struct afsconf_dir *adir = (struct afsconf_dir *) arock;
+ int rc;
+ LOCK_GLOBAL_MUTEX;
+ rc = ((afsconf_SuperUser(adir, acall, NULL) == 0) ? 10029 : 0);
+ UNLOCK_GLOBAL_MUTEX;
+ return rc;
}
#endif /* !defined(UKERNEL) */
-static GetNoAuthFlag(adir)
-struct afsconf_dir *adir; {
+static int
+GetNoAuthFlag(struct afsconf_dir *adir)
+{
if (access(AFSDIR_SERVER_NOAUTH_FILEPATH, 0) == 0) {
- osi_audit ( NoAuthEvent, 0, AUD_END ); /* some random server is running noauth */
- return 1; /* if /usr/afs/local/NoAuth file exists, allow access */
- }
+ osi_audit(NoAuthEvent, 0, AUD_END); /* some random server is running noauth */
+ return 1; /* if /usr/afs/local/NoAuth file exists, allow access */
+ }
return 0;
}
-afsconf_GetNoAuthFlag(adir)
-struct afsconf_dir *adir; {
+int
+afsconf_GetNoAuthFlag(struct afsconf_dir *adir)
+{
int rc;
- LOCK_GLOBAL_MUTEX
+ LOCK_GLOBAL_MUTEX;
rc = GetNoAuthFlag(adir);
- UNLOCK_GLOBAL_MUTEX
+ UNLOCK_GLOBAL_MUTEX;
return rc;
}
-afsconf_SetNoAuthFlag(adir, aflag)
-struct afsconf_dir *adir;
-int aflag; {
+void
+afsconf_SetNoAuthFlag(struct afsconf_dir *adir, int aflag)
+{
register afs_int32 code;
-
- LOCK_GLOBAL_MUTEX
+ LOCK_GLOBAL_MUTEX;
if (aflag == 0) {
/* turn off noauth flag */
- code = ( unlink(AFSDIR_SERVER_NOAUTH_FILEPATH) ? errno : 0 );
- osi_audit ( NoAuthDisableEvent, code, AUD_END );
- }
- else {
+ code = (unlink(AFSDIR_SERVER_NOAUTH_FILEPATH) ? errno : 0);
+ osi_audit(NoAuthDisableEvent, code, AUD_END);
+ } else {
/* try to create file */
- code = open(AFSDIR_SERVER_NOAUTH_FILEPATH, O_CREAT | O_TRUNC | O_RDWR, 0666);
- if (code >= 0) {
- close(code);
- osi_audit ( NoAuthEnableEvent, 0, AUD_END );
- }
- else
- osi_audit ( NoAuthEnableEvent, errno, AUD_END );
+ code =
+ open(AFSDIR_SERVER_NOAUTH_FILEPATH, O_CREAT | O_TRUNC | O_RDWR,
+ 0666);
+ if (code >= 0) {
+ close(code);
+ osi_audit(NoAuthEnableEvent, 0, AUD_END);
+ } else
+ osi_audit(NoAuthEnableEvent, errno, AUD_END);
}
- UNLOCK_GLOBAL_MUTEX
+ UNLOCK_GLOBAL_MUTEX;
}
/* deletes a user from the UserList file */
-afsconf_DeleteUser(adir, auser)
-struct afsconf_dir *adir;
-register char *auser; {
+int
+afsconf_DeleteUser(struct afsconf_dir *adir, register char *auser)
+{
char tbuffer[1024];
char nbuffer[1024];
register FILE *tf;
register FILE *nf;
register int flag;
- char tname[64];
+ char tname[64 + 1];
char *tp;
int found;
struct stat tstat;
register afs_int32 code;
- LOCK_GLOBAL_MUTEX
- strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL);
+ LOCK_GLOBAL_MUTEX;
+ strcompose(tbuffer, sizeof tbuffer, adir->name, "/",
+ AFSDIR_ULIST_FILE, NULL);
#ifndef AFS_NT40_ENV
{
/*
#endif /* AFS_NT40_ENV */
tf = fopen(tbuffer, "r");
if (!tf) {
- UNLOCK_GLOBAL_MUTEX
+ UNLOCK_GLOBAL_MUTEX;
return -1;
}
code = stat(tbuffer, &tstat);
if (code < 0) {
- UNLOCK_GLOBAL_MUTEX
+ UNLOCK_GLOBAL_MUTEX;
return code;
}
strcpy(nbuffer, tbuffer);
nf = fopen(nbuffer, "w+");
if (!nf) {
fclose(tf);
- UNLOCK_GLOBAL_MUTEX
+ UNLOCK_GLOBAL_MUTEX;
return EIO;
}
flag = 0;
while (1) {
/* check for our user id */
tp = fgets(nbuffer, sizeof(nbuffer), tf);
- if (tp == (char *)0) break;
+ if (tp == NULL)
+ break;
code = sscanf(nbuffer, "%64s", tname);
if (code == 1 && strcmp(tname, auser) == 0) {
/* found the guy, don't copy to output file */
found = 1;
- }
- else {
+ } else {
/* otherwise copy original line to output */
fprintf(nf, "%s", nbuffer);
}
}
fclose(tf);
- if (ferror(nf)) flag = 1;
- if (fclose(nf) == EOF) flag = 1;
+ if (ferror(nf))
+ flag = 1;
+ if (fclose(nf) == EOF)
+ flag = 1;
strcpy(nbuffer, tbuffer);
- strcat(nbuffer, ".NXX"); /* generate new file name again */
+ strcat(nbuffer, ".NXX"); /* generate new file name again */
if (flag == 0) {
/* try the rename */
flag = renamefile(nbuffer, tbuffer);
if (flag == 0)
flag = chmod(tbuffer, tstat.st_mode);
- }
- else unlink(nbuffer);
+ } else
+ unlink(nbuffer);
/* finally, decide what to return to the caller */
- UNLOCK_GLOBAL_MUTEX
- if (flag) return EIO; /* something mysterious went wrong */
- if (!found) return ENOENT; /* entry wasn't found, no changes made */
+ UNLOCK_GLOBAL_MUTEX;
+ if (flag)
+ return EIO; /* something mysterious went wrong */
+ if (!found)
+ return ENOENT; /* entry wasn't found, no changes made */
return 0; /* everything was fine */
}
/* returns nth super user from the UserList file */
-afsconf_GetNthUser(adir, an, abuffer, abufferLen)
-struct afsconf_dir *adir;
-afs_int32 an;
-char *abuffer;
-afs_int32 abufferLen; {
+int
+afsconf_GetNthUser(struct afsconf_dir *adir, afs_int32 an, char *abuffer,
+ afs_int32 abufferLen)
+{
char tbuffer[256];
register FILE *tf;
- char tname[64];
+ char tname[64 + 1];
register char *tp;
register int flag;
register afs_int32 code;
- LOCK_GLOBAL_MUTEX
- strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL);
+ LOCK_GLOBAL_MUTEX;
+ strcompose(tbuffer, sizeof tbuffer, adir->name, "/",
+ AFSDIR_ULIST_FILE, NULL);
tf = fopen(tbuffer, "r");
if (!tf) {
- UNLOCK_GLOBAL_MUTEX
+ UNLOCK_GLOBAL_MUTEX;
return 1;
}
flag = 1;
while (1) {
/* check for our user id */
tp = fgets(tbuffer, sizeof(tbuffer), tf);
- if (tp == (char *)0) break;
+ if (tp == NULL)
+ break;
code = sscanf(tbuffer, "%64s", tname);
if (code == 1 && an-- == 0) {
flag = 0;
break;
}
}
- if (flag == 0) strcpy(abuffer, tname);
+ if (flag == 0)
+ strcpy(abuffer, tname);
fclose(tf);
- UNLOCK_GLOBAL_MUTEX
+ UNLOCK_GLOBAL_MUTEX;
return flag;
}
/* returns true iff user is in the UserList file */
-static FindUser(adir, auser)
-struct afsconf_dir *adir;
-register char *auser; {
+static int
+FindUser(struct afsconf_dir *adir, register char *auser)
+{
char tbuffer[256];
register bufio_p bp;
- char tname[64];
- register char *tp;
+ char tname[64 + 1];
register int flag;
register afs_int32 code;
int rc;
- strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL);
+ strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE,
+ NULL);
bp = BufioOpen(tbuffer, O_RDONLY, 0);
- if (!bp) return 0;
+ if (!bp)
+ return 0;
flag = 0;
while (1) {
/* check for our user id */
rc = BufioGets(bp, tbuffer, sizeof(tbuffer));
- if (rc < 0) break;
+ if (rc < 0)
+ break;
code = sscanf(tbuffer, "%64s", tname);
if (code == 1 && strcmp(tname, auser) == 0) {
flag = 1;
}
/* add a user to the user list, checking for duplicates */
-afsconf_AddUser(adir, aname)
-struct afsconf_dir *adir;
-char *aname; {
+int
+afsconf_AddUser(struct afsconf_dir *adir, char *aname)
+{
FILE *tf;
register afs_int32 code;
char tbuffer[256];
- LOCK_GLOBAL_MUTEX
+ LOCK_GLOBAL_MUTEX;
if (FindUser(adir, aname)) {
- UNLOCK_GLOBAL_MUTEX
- return EEXIST; /* already in the list */
+ UNLOCK_GLOBAL_MUTEX;
+ return EEXIST; /* already in the list */
}
- strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL);
+ strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE,
+ NULL);
tf = fopen(tbuffer, "a+");
if (!tf) {
- UNLOCK_GLOBAL_MUTEX
+ UNLOCK_GLOBAL_MUTEX;
return EIO;
}
fprintf(tf, "%s\n", aname);
code = 0;
- if (ferror(tf)) code = EIO;
- if (fclose(tf)) code = EIO;
- UNLOCK_GLOBAL_MUTEX
+ if (ferror(tf))
+ code = EIO;
+ if (fclose(tf))
+ code = EIO;
+ UNLOCK_GLOBAL_MUTEX;
return code;
}
calls finduser on it. If found, returns char * to user string,
otherwise returns NULL. The resulting string should be immediately
copied to other storage prior to release of mutex. */
-static char *CompFindUser(adir, name, sep, inst, realm)
- struct afsconf_dir *adir;
- char *name;
- char *sep;
- char *inst;
- char *realm;
+static char *
+CompFindUser(struct afsconf_dir *adir, char *name, char *sep, char *inst,
+ char *realm)
{
- static char fullname[ MAXKTCNAMELEN + MAXKTCNAMELEN +
- MAXKTCREALMLEN + 3 ];
+ static char fullname[MAXKTCNAMELEN + MAXKTCNAMELEN + MAXKTCREALMLEN + 3];
/* always must have name */
- if ( !name || !name[0] ) { return NULL; }
+ if (!name || !name[0]) {
+ return NULL;
+ }
strcpy(fullname, name);
/* might have instance */
- if ( inst && inst[0] ) {
- if ( !sep || !sep[0] ) { return NULL; }
+ if (inst && inst[0]) {
+ if (!sep || !sep[0]) {
+ return NULL;
+ }
strcat(fullname, sep);
strcat(fullname, inst);
}
/* might have realm */
- if ( realm && realm[0] )
- {
+ if (realm && realm[0]) {
strcat(fullname, "@");
strcat(fullname, realm);
}
- if ( FindUser(adir, fullname) ) {
+ if (FindUser(adir, fullname)) {
return fullname;
} else {
return NULL;
users. Copy the "real name" of the authenticated user into namep
if a pointer is passed.
*/
-afs_int32 afsconf_SuperUser(adir, acall, namep)
-struct afsconf_dir *adir;
-struct rx_call *acall;
-char *namep; {
+afs_int32
+afsconf_SuperUser(struct afsconf_dir *adir, struct rx_call *acall, char *namep)
+{
register struct rx_connection *tconn;
register afs_int32 code;
int flag;
- LOCK_GLOBAL_MUTEX
+ LOCK_GLOBAL_MUTEX;
if (!adir) {
- UNLOCK_GLOBAL_MUTEX
+ UNLOCK_GLOBAL_MUTEX;
return 0;
}
if (afsconf_GetNoAuthFlag(adir)) {
- if (namep) strcpy(namep, "<NoAuth>");
- UNLOCK_GLOBAL_MUTEX
+ if (namep)
+ strcpy(namep, "<NoAuth>");
+ UNLOCK_GLOBAL_MUTEX;
return 1;
}
tconn = rx_ConnectionOf(acall);
code = rx_SecurityClassOf(tconn);
- if (code == 0) {
- UNLOCK_GLOBAL_MUTEX
- return 0; /* not authenticated at all, answer is no */
- }
- else if (code == 1) {
+ if (code == 0) {
+ UNLOCK_GLOBAL_MUTEX;
+ return 0; /* not authenticated at all, answer is no */
+ } else if (code == 1) {
/* bcrypt tokens */
- UNLOCK_GLOBAL_MUTEX
- return 0; /* not supported any longer */
- }
- else if (code == 2) {
+ UNLOCK_GLOBAL_MUTEX;
+ return 0; /* not supported any longer */
+ } else if (code == 2) {
char tname[MAXKTCNAMELEN]; /* authentication from ticket */
char tinst[MAXKTCNAMELEN];
char tcell[MAXKTCREALMLEN];
char tcell_l[MAXKTCREALMLEN];
char *tmp;
-
+
/* keep track of which one actually authorized request */
- char uname[MAXKTCNAMELEN+MAXKTCNAMELEN+MAXKTCREALMLEN+3];
+ char uname[MAXKTCNAMELEN + MAXKTCNAMELEN + MAXKTCREALMLEN + 3];
afs_uint32 exp;
static char lcell[MAXCELLCHARS] = "";
- static char lrealm[AFS_REALM_SZ] = "";
-
+ static char lrealms[AFS_NUM_LREALMS][AFS_REALM_SZ];
+ static int num_lrealms = -1;
+ int lrealm_match = 0, i;
+
/* get auth details from server connection */
- code = rxkad_GetServerInfo
- (acall->conn, (afs_int32 *) 0, &exp,
- tname, tinst, tcell, (afs_int32 *) 0);
+ code =
+ rxkad_GetServerInfo(acall->conn, NULL, &exp, tname, tinst, tcell,
+ NULL);
if (code) {
- UNLOCK_GLOBAL_MUTEX
- return 0; /* bogus connection/other error */
+ UNLOCK_GLOBAL_MUTEX;
+ return 0; /* bogus connection/other error */
}
/* don't bother checking anything else if tix have expired */
#ifdef AFS_PTHREAD_ENV
- if (exp < clock_Sec()) {
+ if (exp < clock_Sec()) {
#else
- if (exp < FT_ApproxTime()) {
+ if (exp < FT_ApproxTime()) {
#endif
- UNLOCK_GLOBAL_MUTEX
- return 0; /* expired tix */
+ UNLOCK_GLOBAL_MUTEX;
+ return 0; /* expired tix */
}
/* generate lowercased version of cell name */
strcpy(tcell_l, tcell);
tmp = tcell_l;
- while ( *tmp ) { *tmp = tolower(*tmp); *tmp++; }
+ while (*tmp) {
+ *tmp = tolower(*tmp);
+ tmp++;
+ }
/* determine local cell name. It's static, so will only get
- calculated the first time through */
+ * calculated the first time through */
if (!lcell[0])
afsconf_GetLocalCell(adir, lcell, sizeof(lcell));
/* if running a krb environment, also get the local realm */
/* note - this assumes AFS_REALM_SZ <= MAXCELLCHARS */
/* just set it to lcell if it fails */
- if (!lrealm[0]) {
- if (afs_krb_get_lrealm(lrealm, 0) != 0) /* KSUCCESS */
- strncpy(lrealm, lcell, AFS_REALM_SZ);
+ if (num_lrealms == -1) {
+ for (i=0; i<AFS_NUM_LREALMS; i++) {
+ if (afs_krb_get_lrealm(lrealms[i], i) != 0 /*KSUCCESS*/)
+ break;
+ }
+
+ if (i == 0) {
+ strncpy(lrealms[0], lcell, AFS_REALM_SZ);
+ num_lrealms = 1;
+ } else {
+ num_lrealms = i;
+ }
+ }
+
+ /* See if the ticket cell matches one of the local realms */
+ lrealm_match = 0;
+ for ( i=0;i<num_lrealms;i++ ) {
+ if (!strcasecmp(lrealms[i], tcell)) {
+ lrealm_match = 1;
+ break;
+ }
}
+ /* If yes, then make sure that the name is not present in
+ * an exclusion list */
+ if (lrealm_match) {
+ if (tinst[0])
+ snprintf(uname,sizeof(uname),"%s.%s@%s",tname,tinst,tcell);
+ else
+ snprintf(uname,sizeof(uname),"%s@%s",tname,tcell);
+
+ if (afs_krb_exclusion(uname))
+ lrealm_match = 0;
+ }
/* start with no uname and no authorization */
strcpy(uname, "");
flag = 0;
/* localauth special case */
- if ( strlen(tinst) == 0 && strlen(tcell) == 0 &&
- !strcmp(tname, AUTH_SUPERUSER) ) {
+ if (strlen(tinst) == 0 && strlen(tcell) == 0
+ && !strcmp(tname, AUTH_SUPERUSER)) {
strcpy(uname, "<LocalAuth>");
flag = 1;
- /* cell of connection matches local cell or krb4 realm */
- } else if ( !strcasecmp(tcell, lcell) || !strcasecmp(tcell,lrealm) ) {
- if ( (tmp = CompFindUser(adir, tname, ".", tinst, NULL)) ) {
+ /* cell of connection matches local cell or one of the realms */
+ } else if (!strcasecmp(tcell, lcell) || lrealm_match) {
+ if ((tmp = CompFindUser(adir, tname, ".", tinst, NULL))) {
strcpy(uname, tmp);
flag = 1;
#ifdef notyet
- } else if ( (tmp = CompFindUser(adir, tname, "/", tinst, NULL)) ) {
+ } else if ((tmp = CompFindUser(adir, tname, "/", tinst, NULL))) {
strcpy(uname, tmp);
flag = 1;
#endif
}
-
- /* cell of conn doesn't match local cell or realm */
+ /* cell of conn doesn't match local cell or realm */
} else {
- if ( (tmp = CompFindUser(adir, tname, ".", tinst, tcell)) ) {
+ if ((tmp = CompFindUser(adir, tname, ".", tinst, tcell))) {
strcpy(uname, tmp);
flag = 1;
#ifdef notyet
- } else if ( (tmp = CompFindUser(adir, tname, "/", tinst, tcell)) ) {
+ } else if ((tmp = CompFindUser(adir, tname, "/", tinst, tcell))) {
strcpy(uname, tmp);
flag = 1;
#endif
- } else if ( (tmp = CompFindUser(adir, tname, ".", tinst, tcell_l)) ) {
+ } else if ((tmp = CompFindUser(adir, tname, ".", tinst, tcell_l))) {
strcpy(uname, tmp);
flag = 1;
#ifdef notyet
- } else if ( (tmp = CompFindUser(adir, tname, "/", tinst, tcell_l)) ) {
+ } else if ((tmp = CompFindUser(adir, tname, "/", tinst, tcell_l))) {
strcpy(uname, tmp);
flag = 1;
#endif
if (namep)
strcpy(namep, uname);
- UNLOCK_GLOBAL_MUTEX
+ UNLOCK_GLOBAL_MUTEX;
return flag;
- }
- else { /* some other auth type */
- UNLOCK_GLOBAL_MUTEX
- return 0; /* mysterious, just say no */
+ } else { /* some other auth type */
+ UNLOCK_GLOBAL_MUTEX;
+ return 0; /* mysterious, just say no */
}
}