Page MenuHomePhorge

No OneTemporary

Authored By
Unknown
Size
30 KB
Referenced Files
None
Subscribers
None
diff --git a/lib/auth_krb_pts.c b/lib/auth_krb_pts.c
new file mode 100644
index 000000000..e4aaa4f26
--- /dev/null
+++ b/lib/auth_krb_pts.c
@@ -0,0 +1,475 @@
+#include <krb.h>
+#include <sys/wait.h>
+#include "auth_krb_pts.h"
+
+#ifndef KRB_MAPNAME
+#define KRB_MAPNAME "/etc/krb.equiv"
+#endif
+
+static char auth_userid[PR_MAXNAMELEN] = "anonymous";
+static char auth_name[PR_MAXNAMELEN] = "anonymous";
+static char auth_aname[ANAME_SZ] = "anonymous";
+static char auth_inst[INST_SZ] = "";
+static char auth_realm[REALM_SZ] = "";
+
+
+/*
+ cdecl> declare x as pointer to array of array 64 of char
+ char (*x)[][64]
+ */
+static char (*auth_groups)[][PR_MAXNAMELEN]=NULL;
+static int auth_ngroups=0;
+
+/*
+ * Determine if the user is a member of 'identifier'
+ * Returns one of:
+ * 0 User does not match identifier
+ * 1 identifier matches everybody
+ * 2 User is in the group that is identifier
+ * 3 User is identifer
+ */
+int auth_memberof(identifier)
+char *identifier;
+{
+ int i;
+
+ if (strcmp(identifier, "anyone") == 0) return 1;
+
+ if (strcmp(identifier, auth_userid) == 0) return 3;
+
+ /* "anonymous" is not a member of any group */
+ if (strcmp(auth_userid, "anonymous") == 0) return 0;
+
+ for (i=0;i<auth_ngroups;i++)
+ if (!strcmp(identifier,(*auth_groups)[i]))
+ return 2;
+
+ return 0;
+}
+
+
+/*
+ * Parse a line 'src' from an /etc/krb.equiv file.
+ * Sets the buffer pointed to by 'principal' to be the kerberos
+ * identity and sets the buffer pointed to by 'localuser' to
+ * be the local user. Both buffers must be of size one larger than
+ * MAX_K_NAME_SZ. Returns 1 on success, 0 on failure.
+ */
+static int parse_krbequiv_line(src, principal, localuser)
+char *src;
+char *principal;
+char *localuser;
+{
+ int i;
+
+ while (isspace(*src)) src++;
+ if (!*src) return 0;
+
+ for (i = 0; *src && !isspace(*src); i++) {
+ if (i >= MAX_K_NAME_SZ) return 0;
+ *principal++ = *src++;
+ }
+ *principal = 0;
+
+ if (!isspace(*src)) return 0; /* Need at least one separator */
+ while (isspace(*src)) src++;
+ if (!*src) return 0;
+
+ for (i = 0; *src && !isspace(*src); i++) {
+ if (i >= MAX_K_NAME_SZ) return 0;
+ *localuser++ = *src++;
+ }
+ *localuser = 0;
+ return 1;
+}
+
+/*
+ * Map a remote kerberos principal to a local username. If a mapping
+ * is found, a pointer to the local username is returned. Otherwise,
+ * a NULL pointer is returned.
+ * Eventually, this may be more sophisticated than a simple file scan.
+ */
+char *auth_map_krbid(real_aname, real_inst, real_realm)
+char *real_aname;
+char *real_inst;
+char *real_realm;
+{
+ static char localuser[MAX_K_NAME_SZ + 1];
+ char principal[MAX_K_NAME_SZ + 1];
+ char aname[ANAME_SZ];
+ char inst[INST_SZ];
+ char realm[REALM_SZ];
+ char lrealm[REALM_SZ];
+ char krbhst[MAX_HSTNM];
+ char *p;
+ char buf[1024];
+ FILE *mapfile;
+
+ if (!(mapfile = fopen(KRB_MAPNAME, "r"))) {
+ /* If the file can't be opened, don't do mappings */
+ return 0;
+ }
+
+ for (;;) {
+ if (!fgets(buf, sizeof(buf), mapfile)) break;
+ if (parse_krbequiv_line(buf, principal, localuser) == 0 ||
+ kname_parse(aname, inst, realm, principal) != 0) {
+ /* Ignore badly formed lines */
+ continue;
+ }
+ if (!strcmp(aname, real_aname) && !strcmp(inst, real_inst) &&
+ !strcmp(realm, real_realm)) {
+ fclose(mapfile);
+
+ aname[0] = inst[0] = realm[0] = '\0';
+ if (kname_parse(aname, inst, realm, localuser) != 0) {
+ return 0;
+ }
+
+ /* Upcase realm name */
+ for (p = realm; *p; p++) {
+ if (islower(*p)) *p = toupper(*p);
+ }
+
+ if (*realm) {
+ if (krb_get_lrealm(lrealm,1)) {
+ return 0; /* configuration error */
+ }
+ if (strcmp(lrealm, realm) == 0) {
+ *realm = 0;
+ }
+ else if (krb_get_krbhst(krbhst, realm, 0)) {
+ return 0; /* Unknown realm */
+ }
+ }
+
+ strcpy(localuser, aname);
+ if (*inst) {
+ strcat(localuser, ".");
+ strcat(localuser, inst);
+ }
+ if (*realm) {
+ strcat(localuser, "@");
+ strcat(localuser, realm);
+ }
+
+ return localuser;
+ }
+ }
+
+ fclose(mapfile);
+ return 0;
+}
+
+/*
+ * Convert 'identifier' into canonical form.
+ * Returns a pointer to a static buffer containing the canonical form
+ * or NULL if 'identifier' is invalid.
+ */
+char *auth_canonifyid(identifier)
+char *identifier;
+{
+ static char retbuf[MAX_K_NAME_SZ+1];
+ char aname[ANAME_SZ];
+ char inst[INST_SZ];
+ char realm[REALM_SZ];
+ char lrealm[REALM_SZ];
+ char krbhst[MAX_HSTNM];
+ char *p;
+
+ if (strcasecmp(identifier, "anonymous") == 0) {
+ return "anonymous";
+ }
+ if (strcasecmp(identifier, "anybody") == 0 ||
+ strcasecmp(identifier, "anyone") == 0) {
+ return "anyone";
+ }
+
+ aname[0] = inst[0] = realm[0] = '\0';
+ if (kname_parse(aname, inst, realm, identifier) != 0) {
+ return 0;
+ }
+
+ /* Upcase realm name */
+ for (p = realm; *p; p++) {
+ if (islower(*p)) *p = toupper(*p);
+ }
+
+ if (*realm) {
+ if (krb_get_lrealm(lrealm,1)) {
+ return 0; /* configuration error */
+ }
+ if (strcmp(lrealm, realm) == 0) {
+ *realm = 0;
+ }
+ else if (krb_get_krbhst(krbhst, realm, 0)) {
+ return 0; /* Unknown realm */
+ }
+ }
+
+
+ /* Check for krb.equiv remappings. */
+ if (p = auth_map_krbid(aname, inst, realm)) {
+ strcpy(retbuf, p);
+ return retbuf;
+ }
+
+ strcpy(retbuf, aname);
+ if (*inst) {
+ strcat(retbuf, ".");
+ strcat(retbuf, inst);
+ }
+ if (*realm) {
+ strcat(retbuf, "@");
+ strcat(retbuf, realm);
+ }
+
+ return retbuf;
+}
+
+
+/*
+ * Set the current user to 'identifier'
+ *
+ * This function also fetches the list of groups the user is a member of and
+ * stores them in a static array. The system uses a berkely DB database as a
+ * means of communication between this library and the external program that
+ * contacts the PTS server. The database also caches this information using an
+ * optional fixed length cache key provided by the caller (assuming the calling
+ * program uses the session's encryption key, this allows users to force the
+ * cache to be updated by re-authenticating themselves.) For programs that do
+ * not have access to a useful object to use as an identifier, the userid is
+ * used instead (with up to 3 nulls at the end to round the length up to a
+ * multiple of 4).
+ * Two different kinds of objects are stored in the database. One is a "header"
+ * containing the userid (for verification), the time the record was last
+ * updated, and the number of groups the user is a member of. The database key
+ * for this entry is formed by appending an 'H' and 3 nulls to the base
+ * key. The other object in the database is the actual list of groups. This is
+ * stored in a contigous array of fixed (maximum) length strings. The key for
+ * this object is formed by appending a 'D' and 3 nulls to the base key.
+ */
+
+
+int auth_setid(char *identifier, char *cacheid) {
+ DBT key, dataheader,datalist;
+ char keydata[PR_MAXNAMELEN + 4]; /* or 20, whichever is greater */
+ int fd,rc,xpid;
+ DB *ptdb;
+ HASHINFO info;
+ ptluser us;
+
+ if (auth_ngroups) {
+ free(auth_groups);
+ auth_groups=NULL;
+ auth_ngroups=0;
+ }
+ identifier = auth_canonifyid(identifier);
+ if (!identifier) return -1;
+ auth_aname[0] = auth_inst[0] = auth_realm[0] = '\0';
+ kname_parse(auth_aname, auth_inst, auth_realm, identifier);
+ if (strcmp(auth_userid, "anyone") == 0) return 0;
+ strcpy(auth_userid, identifier);
+
+ info.hash=hashfn;
+ info.lorder=0;
+ info.bsize=2048;
+ info.cachesize=20480;
+ info.ffactor=8;
+ key.data=keydata;
+ key.size=20;
+ fd=open(DBLOCK, O_CREAT|O_TRUNC|O_RDWR, 0644);
+ if (fd == -1) {
+ syslog(LOG_ERR, "IOERROR: creating lock file %s: %m", DBLOCK);
+ return -1;
+ }
+ if (lock_shared(fd) < 0) {
+ syslog(LOG_ERR, "IOERROR: locking lock file %s: %m", DBLOCK);
+ return -1;
+ }
+ ptdb=dbopen(DBFIL,O_RDONLY,0,DB_HASH,&info);
+ if (!ptdb)
+ if (errno == ENOENT) {
+ /* Hopefully, this should prevent two different processes from trying
+ to crete the database at the same time */
+ ptdb=dbopen(DBFIL,O_CREAT|O_RDWR|O_EXCL,0644,DB_HASH,&info);
+ if (!ptdb && errno == EEXIST) {
+ ptdb=dbopen(DBFIL,O_RDONLY,0,DB_HASH,&info);
+ if (!ptdb) {
+ syslog(LOG_ERR, "IOERROR: opening database %s: %m", DBFIL);
+ close(fd);
+ return -1;
+ }
+ } else if (!ptdb) {
+ syslog(LOG_ERR, "IOERROR: creating database %s: %m", DBFIL);
+ return -1;
+ } else {
+ /* Write a record to the database, so that the database header
+ will be written out */
+ memset(key.data,0,key.size);
+ strcpy(key.data,"DUMMYREC");
+ dataheader.size=5;
+ dataheader.data="NULL";
+ if (PUT(ptdb,&key,&dataheader,0) < 0) {
+ syslog(LOG_ERR, "IOERROR: initializing database %s: %m",
+ DBFIL);
+ return -1;
+ }
+ /* close and reopen the database in read-only mode */
+ if (CLOSE(ptdb) <0 ) {
+ syslog(LOG_ERR, "IOERROR: initializing database %s: %m",
+ DBFIL);
+ return -1;
+ }
+ ptdb=dbopen(DBFIL,O_RDONLY,0644,DB_HASH,&info);
+ if (!ptdb) {
+ syslog(LOG_ERR, "IOERROR: reopening new database %s: %m",
+ DBFIL);
+ return -1;
+ }
+ }
+ } else {
+ syslog(LOG_ERR, "IOERROR: opening database %s: %m", DBFIL);
+ return -1;
+ }
+ if (cacheid) {
+ memset(key.data,0,key.size);
+ memcpy(key.data,cacheid,16);
+ key.size=20;
+ } else {
+ key.size=PR_MAXNAMELEN + 4;
+ if ((strlen(identifier) + 5 ) < PR_MAXNAMELEN)
+ /* round length up to nearest multiple of 4
+ so that the the hash function works properly */
+ key.size=(((strlen(identifier) + 3) >> 2) << 2) + 4;
+ memset(key.data,0,key.size);
+ strncpy(key.data,identifier,key.size-4);
+ }
+ /* Fetch and process the header record for the user, if any */
+ keydata[key.size-4]='H';
+ rc=GET(ptdb,&key,&dataheader,0);
+ keydata[key.size-4]=0;
+ if (rc < 0) {
+ syslog(LOG_ERR, "IOERROR: reading database: %m");
+ CLOSE(ptdb);
+ close(fd);
+ return -1;
+ }
+ if (!rc) {
+ if(dataheader.size != sizeof(ptluser)) {
+ syslog(LOG_ERR, "IOERROR: Database probably corrupt");
+ CLOSE(ptdb);
+ close(fd);
+ return -1;
+ }
+ /* make sure the record is alignes */
+ memcpy(&us,dataheader.data,sizeof(ptluser));
+ }
+ if (rc || (!cacheid && us.cached < time(0) - EXPIRE_TIME)) {
+ int pfd[2];
+ int pid;
+ /* There's no record for this user. close the database, and run the
+ external lookup client */
+ CLOSE(ptdb);
+ close(fd);
+ if (pipe(pfd) < 0) {
+ syslog(LOG_ERR, "pipe: %m");
+ return -1;
+ }
+ pid=vfork();
+ if (pid< 0) {
+ syslog(LOG_ERR, "vfork: %m");
+ close(pfd[0]);
+ close(pfd[1]);
+ return -1;
+ }
+ if (!pid) {
+ close(pfd[1]);
+ dup2(pfd[0],0);
+ execl(PTCLIENT,PTCLIENT,0);
+ syslog(LOG_ERR, "exec: %m");
+ exit(-1);
+ } else {
+ /* The data passed along the pipe is as follows:
+ Size of the cache tag, followed by the tag itself (variable
+ length) then the username, in a fixed-length string */
+ write(pfd[1],&key.size,sizeof(size_t));
+ write(pfd[1],key.data,key.size);
+ write(pfd[1],identifier,PR_MAXNAMELEN);
+ close(pfd[1]);
+ xpid=waitpid(pid,&rc,0);
+ if (xpid==-1 || WEXITSTATUS(rc) != 0) {
+ return -1;
+ }
+ /* The database must be re-opened after external modifications, at
+ least in db 1.1.85 */
+ fd=open(DBLOCK, O_CREAT|O_TRUNC|O_RDWR, 0644);
+ if (fd == -1){
+ syslog(LOG_ERR, "IOERROR: creating lock file %s: %m", DBLOCK);
+ return -1;
+ }
+ if (lock_shared(fd) < 0) {
+ syslog(LOG_ERR, "IOERROR: locking lock file %s: %m", DBLOCK);
+ return -1;
+ }
+ ptdb=dbopen(DBFIL,O_RDONLY,0,DB_HASH,&info);
+ if (!ptdb) {
+ syslog(LOG_ERR, "IOERROR: opening database %s: %m", DBFIL);
+ close(fd);
+ return -1;
+ }
+ }
+ /* fetch the new header record and proces it */
+ keydata[key.size-4]='H';
+ rc=GET(ptdb,&key,&dataheader,0);
+ keydata[key.size-4]=0;
+ if (rc < 0) {
+ syslog(LOG_ERR, "IOERROR: reading database: %m");
+ CLOSE(ptdb);
+ close(fd);
+ return -1;
+ }
+ /* The record still isn't there, even though the child claimed sucess
+ */
+ if (rc) {
+ syslog(LOG_ERR, "Sucessful %s run did not update database",
+ PTCLIENT);
+ CLOSE(ptdb);
+ close(fd);
+ return -1;
+ }
+ memcpy(&us,dataheader.data,dataheader.size);
+ }
+ /* We assume cache keys will be unique. This will catch duplicates if they
+ occur */
+ if (strcasecmp(identifier,us.user)) {
+ syslog(LOG_ERR,
+ "Fetched record for user %s was for user %s: key not unique",
+ identifier, us.user);
+ CLOSE(ptdb);
+ close(fd);
+ return -1;
+ }
+ /* now get the actual data from the database. this will be a contiguous
+ char[][] of size PR_MAXNAMELEN * us.ngroups */
+ keydata[key.size-4]='D';
+ rc=GET(ptdb,&key,&datalist,0);
+ CLOSE(ptdb);
+ close(fd);
+ if (rc < 0) {
+ syslog(LOG_ERR, "IOERROR: reading database: %m");
+ return -1;
+ }
+ if (rc) {
+ syslog(LOG_ERR,
+ "Database inconsistent: header record found, data record missing");
+ return -1;
+ }
+ auth_ngroups=us.ngroups;
+ if (auth_ngroups) {
+ auth_groups=(char (*)[][PR_MAXNAMELEN])xmalloc(auth_ngroups *
+ PR_MAXNAMELEN);
+ memcpy(auth_groups,datalist.data, auth_ngroups*PR_MAXNAMELEN);
+ }
+ return 0;
+}
diff --git a/lib/auth_krb_pts.h b/lib/auth_krb_pts.h
new file mode 100644
index 000000000..a06f0042a
--- /dev/null
+++ b/lib/auth_krb_pts.h
@@ -0,0 +1,50 @@
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <sys/file.h>
+#include <errno.h>
+#include <db.h>
+#include <syslog.h>
+#include <ctype.h>
+#include <afs/ptserver.h>
+#include <afs/cellconfig.h>
+
+#define DBFIL "pts.db"
+#define DBLOCK "ptlock"
+#define PTCLIENT "ptloader"
+
+typedef struct {
+ time_t cached;
+ char user[PR_MAXNAMELEN];
+ int ngroups;
+} ptluser;
+
+
+#define CLOSE(db) (db)->close((db))
+#define GET(db,key,data,flags) (db)->get((db),(key),(data),(flags))
+#define PUT(db,key,data,flags) (db)->put((db),(key),(data),(flags))
+#define SEQ(db,key,data,flags) (db)->seq((db),(key),(data),(flags))
+#define DEL(db,key,flags) (db)->del((db),(key),(flags))
+#define SYNC(db,flags) (db)->sync((db),(flags))
+#define EXPIRE_TIME 7200 /* 2 hours */
+
+extern int errno;
+
+/* Do not make this unsigned. you'll lose! (db won't open the file) */
+static int32_t hashfn(const void *data, size_t size) {
+ int32_t ret,val;
+ int i;
+ ret=0;
+ if (size %4) {
+ syslog(LOG_WARNING,
+ "Database key size %d not multiple of 4; continuing anyway",
+ size);
+ }
+ for (i=0;i*4<size;i++) {
+ memcpy(&val,data+4*i,4);
+ ret=ret^val;
+ }
+ return ret;
+}
+
+
diff --git a/ptclient/Makefile.in b/ptclient/Makefile.in
new file mode 100644
index 000000000..537937a6b
--- /dev/null
+++ b/ptclient/Makefile.in
@@ -0,0 +1,84 @@
+# Makefile for amssync
+#
+# @configure_input@
+#
+# (C) Copyright 1995 by Carnegie Mellon University
+#
+# All Rights Reserved
+#
+# Permission to use, copy, modify, distribute, and sell this software
+# and its documentation for any purpose is hereby granted without
+# fee, provided that the above copyright notice appear in all copies
+# and that both that copyright notice and this permission notice
+# appear in supporting documentation, and that the name of Carnegie
+# Mellon University not be used in advertising or publicity
+# pertaining to distribution of the software without specific,
+# written prior permission. Carnegie Mellon University makes no
+# representations about the suitability of this software for any
+# purpose. It is provided "as is" without express or implied
+# warranty.
+#
+# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+# SOFTWARE.
+#
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+INSTALL = @INSTALL@
+RANLIB = @RANLIB@
+
+DEFS = @DEFS@
+CPPFLAGS = -I. -I$(srcdir) -I$(srcdir)/../lib -I$(srcdir)/../et -I../../db/include @CPPFLAGS@
+AFSLIBS =/usr/local/lib/afs/libprot.a /usr/local/lib/libubik.a /usr/local/lib/afs/libauth.a /usr/local/lib/afs/libsys.a /usr/local/lib/librxkad.a /usr/local/lib/librx.a /usr/local/lib/afs/libaudit.a /usr/local/lib/liblwp.a /usr/local/lib/afs/util.a /usr/local/lib/libcom_err.a
+LIBS = -ldb @LIBS@
+DEPLIBS = ../lib/libcyrus.a @DEPLIBS@
+
+CFLAGS = -g
+LDFLAGS = -g -L$(DB)
+
+SHELL = /bin/sh
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+cyrus_prefix = @cyrus_prefix@
+
+#Fixme...
+AFS=/usr/local
+DB=../../db/PORT/sunos.4.1.3
+
+all: ptloader ptexpire pttest
+
+install:
+ $(INSTALL) -s -m 755 ptloader $(DESTDIR)$(cyrus_prefix)/etc
+ $(INSTALL) -s -m 755 ptexpire $(DESTDIR)$(cyrus_prefix)/etc
+
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) $(CFLAGS) $<
+
+ptloader: ptloader.o $(DEPLIBS)
+ $(CC) $(LDFLAGS) -o $@ ptloader.o $(DEPLIBS) $(AFSLIBS) $(LIBS)
+
+ptexpire: ptexpire.o $(DEPLIBS)
+ $(CC) $(LDFLAGS) -o $@ ptexpire.o $(DEPLIBS) $(LIBS)
+
+#pttest: pttest.o auth_krb_pts.o $(DEPLIBS)
+# $(CC) $(LDFLAGS) -o $@ pttest.o auth_krb_pts.o $(OBJS) $(DEPLIBS) $(LIBS)
+clean:
+ rm -f *.o Makefile.bak ptexpire ptloader
+
+distclean: clean
+ rm -f Makefile
+
+depend:
+ makedepend $(CPPFLAGS) $(DEFS) $(CFLAGS) *.c $(srcdir)/*.c
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
diff --git a/ptclient/ptexpire.c b/ptclient/ptexpire.c
new file mode 100644
index 000000000..eb7fd7c68
--- /dev/null
+++ b/ptclient/ptexpire.c
@@ -0,0 +1,204 @@
+#include "auth_krb_pts.h"
+
+typedef struct {
+ char keydata[PR_MAXNAMELEN + 4];
+ int keysize;
+ char user[PR_MAXNAMELEN];
+} delrec,*dellist;
+
+static int ndels,ndalloc;
+
+/* This program purges old entries from the database. It holds an exclusive
+ lock throughout the process. The reaseon for the split data
+ gathering/expunge phases is because DB's SEQ operator breaks if the database
+ is modified while the database is being sequenced through.
+ */
+int main(int argc, char *argv) {
+ HASHINFO info;
+ DB * ptdb;
+ char keydata[PR_MAXNAMELEN+4],*thekey;
+ namelist groups;
+ int i,j,found,fd,rc;
+ DBT key,data;
+ ptluser us;
+ size_t size;
+ time_t timenow;
+ dellist deletions;
+
+
+ openlog("ptexpire",LOG_PID,LOG_LOCAL6);
+
+
+ timenow=time(0);
+ ndels=0;
+ ndalloc=10;
+ deletions=(dellist)xmalloc((ndalloc + 1)*sizeof(delrec));
+
+
+ info.hash=hashfn;
+ info.lorder=0;
+ info.bsize=2048;
+ info.cachesize=20480;
+ info.ffactor=8;
+ fd=open(DBLOCK, O_CREAT|O_TRUNC|O_RDWR, 0644);
+ if (fd == -1) {
+ syslog(LOG_ERR, "IOERROR: creating lock file %s: %m", DBLOCK);
+ return -1;
+ }
+ if (lock_blocking(fd) < 0) {
+ syslog(LOG_ERR, "IOERROR: locking lock file %s: %m", DBLOCK);
+ return -1;
+ }
+ ptdb=dbopen(DBFIL,O_RDWR,0,DB_HASH,&info);
+ if (!ptdb) {
+ syslog(LOG_ERR, "IOERROR: opening database %s: %m", DBFIL);
+ return -1;
+ }
+ rc=SEQ(ptdb,&key,&data,R_FIRST);
+ if (rc < 0) {
+ syslog(LOG_ERR, "IOERROR: reading database %s: %m", DBFIL);
+ return -1;
+ }
+ if (rc)
+ exit(0);
+ thekey=key.data;
+#ifdef DEBUG
+ printf("Processing entry with key:");
+ for (i=0;i<key.size;i++)
+ if (isprint(thekey[i]))
+ printf("%c",thekey[i]);
+ else
+ printf("\\%.3o", thekey[i]);
+ printf("\n");
+#endif
+ if (thekey[key.size-4] == 'H') {
+ if (data.size != sizeof(ptluser)) {
+ syslog(LOG_ERR, "IOERROR: Database probably corrupt");
+ return -1;
+ }
+
+ memcpy(&us,data.data,data.size);
+#ifdef DEBUG
+ printf("Found header record for user %s\n", us.user);
+#endif
+ if (us.cached + EXPIRE_TIME < timenow) {
+#ifdef DEBUG
+ printf("record expired, marking for deletion\n");
+#endif
+ if (ndels > ndalloc) {
+ ndalloc *=2;
+ deletions=(dellist)xrealloc(deletions,(ndalloc + 1)
+ * sizeof(delrec));
+ }
+ deletions[ndels].keysize=key.size;
+ memcpy(deletions[ndels].keydata,key.data,key.size);
+ strcpy(deletions[ndels].user,us.user);
+ ndels++;
+ }
+ }
+ found=1;
+ while (found) {
+ rc=SEQ(ptdb,&key,&data,R_NEXT);
+ found=(rc == 0);
+ if (rc < 0) {
+ syslog(LOG_ERR, "IOERROR: reading database %s: %m", DBFIL);
+ return -1;
+ }
+
+ if (rc == 0) {
+ thekey=key.data;
+#ifdef DEBUG
+ printf("Processing entry with key:");
+ thekey=key.data;
+ for (i=0;i<key.size;i++)
+ if (isprint(thekey[i]))
+ printf("%c",thekey[i]);
+ else
+ printf("\\%.3o", thekey[i]);
+ printf("\n");
+#endif
+ if (thekey[key.size-4] == 'H') {
+ if (data.size != sizeof(ptluser)) {
+ syslog(LOG_ERR, "IOERROR: Database probably corrupt");
+ CLOSE(ptdb);
+ close(fd);
+ return -1;
+ }
+ memcpy(&us,data.data,data.size);
+#ifdef DEBUG
+ printf("Found header record for user %s\n", us.user);
+#endif
+ if (us.cached + EXPIRE_TIME < timenow) {
+#ifdef DEBUG
+ printf("record expired, marking for deletion\n");
+#endif
+ if (ndels > ndalloc) {
+ ndalloc *=2;
+ deletions=(dellist)xrealloc(deletions,(ndalloc + 1) *
+ sizeof(delrec));
+ }
+ deletions[ndels].keysize=key.size;
+ memcpy(deletions[ndels].keydata,key.data,key.size);
+ strcpy(deletions[ndels].user,us.user);
+ ndels++;
+ }
+ }
+ }
+ }
+
+ for (j=0;j<ndels;j++) {
+ key.size=deletions[j].keysize;
+ key.data=deletions[j].keydata;
+ thekey=key.data;
+#ifdef DEBUG
+ printf("User %s: Key: ", deletions[j].user);
+ for (i=0;i<key.size;i++)
+ if (isprint(thekey[i]))
+ printf("%c",thekey[i]);
+ else
+ printf("\\%.3o", thekey[i]);
+ printf("\n");
+
+ printf("Expunging header....");
+#endif
+ rc=DEL(ptdb,&key,0);
+ if (rc < 0) {
+ syslog(LOG_ERR, "IOERROR: writing database %s: %m", DBFIL);
+ CLOSE(ptdb);
+ close(fd);
+ return -1;
+ }
+ if (rc) {
+ syslog(LOG_ERR, "Aiee. header record disappeared!");
+ CLOSE(ptdb);
+ close(fd);
+ return -1;
+ }
+#ifdef DEBUG
+ printf("data....");
+#endif
+ thekey[key.size-4]='D';
+ rc=DEL(ptdb,&key,0);
+ if (rc < 0) {
+ syslog(LOG_ERR, "IOERROR: writing database %s: %m", DBFIL);
+ CLOSE(ptdb);
+ return -1;
+ }
+ if (rc) {
+ syslog(LOG_ERR, "Data record missing, continuing anyway");
+ }
+#ifdef DEBUG
+ printf("done\n");
+#endif
+ }
+
+ CLOSE(ptdb);
+ close(fd);
+
+ free(deletions);
+ exit(0);
+}
+int fatal(char *msg, int exitcode) {
+ syslog(LOG_ERR,"%s", msg);
+ exit(-1);
+}
diff --git a/ptclient/ptloader.c b/ptclient/ptloader.c
new file mode 100644
index 000000000..384083efe
--- /dev/null
+++ b/ptclient/ptloader.c
@@ -0,0 +1,122 @@
+#include "auth_krb_pts.h"
+
+/* This program does the actual work of contacting the PTS server and updating
+ the database. it reads the base database key and username from stdin */
+int main(int argc, char *argv) {
+ HASHINFO info;
+ DB * ptdb;
+ char indata[PR_MAXNAMELEN+4];
+ char user[PR_MAXNAMELEN];
+ namelist groups;
+ int i,fd,rc;
+ DBT key,dataheader,datalist;
+ ptluser us;
+ char (*list)[][PR_MAXNAMELEN];
+ size_t size;
+ openlog(PTCLIENT,LOG_PID,LOG_LOCAL6);
+
+
+ memset(indata,0,PR_MAXNAMELEN+4);
+
+ if (read(0,&size,sizeof(size_t)) < 0) {
+ syslog(LOG_ERR,"read from pipe: %m");
+ exit(-1);
+ }
+ if (read(0,indata,size) < 0) {
+ syslog(LOG_ERR,"read from pipe: %m");
+ exit (-1);
+ }
+ key.data=indata;
+ key.size=size;
+ if (read(0,user,PR_MAXNAMELEN) < 0) {
+ syslog(LOG_ERR,"read from pipe: %m");
+ exit (-1);
+ }
+#ifdef DEBUG
+ printf("Ptclient got user %s\ncache val: ", user);
+ for (i=0;i<size;i++)
+ if (isprint(indata[i]))
+ printf("%c",indata[i]);
+ else
+ printf("\\%.3o", indata[i]);
+ printf("\n");
+#endif
+ info.hash=hashfn;
+ info.lorder=0;
+ info.bsize=2048;
+ info.cachesize=20480;
+ info.ffactor=8;
+ /* Get group list from PTS */
+ if ((rc=pr_Initialize(1L,AFSCONF_CLIENTNAME,0))) {
+ syslog(LOG_ERR, "pr_Initialize: %s", error_message(rc));
+ exit(-1);
+ }
+ if ((rc=pr_ListMembers(user,&groups))) {
+ syslog(LOG_ERR, "pr_ListMembers %s: %s", user, error_message(rc));
+ exit(-1);
+ }
+ us.ngroups=groups.namelist_len;
+ us.cached=time(0);
+ /* store group list in contiguous array for easy storage in the database */
+ list=(char (*)[][PR_MAXNAMELEN])xmalloc(us.ngroups*PR_MAXNAMELEN);
+ memset(list,0,us.ngroups*PR_MAXNAMELEN);
+ for (i=0;i<us.ngroups;i++){
+ strcpy((*list)[i],groups.namelist_val[i]);
+ }
+ pr_End();
+ /* build and store a header record for this user */
+ strcpy(us.user,user);
+ dataheader.data=&us;
+ dataheader.size=sizeof(ptluser);
+ datalist.data=list;
+ datalist.size=us.ngroups*PR_MAXNAMELEN;
+ indata[key.size-4]='H';
+
+ fd=open(DBLOCK, O_CREAT|O_TRUNC|O_RDWR, 0644);
+ if (fd == -1) {
+ syslog(LOG_ERR, "IOERROR: creating lock file %s: %m", DBLOCK);
+ return -1;
+ }
+ if (lock_blocking(fd) < 0) {
+ syslog(LOG_ERR, "IOERROR: locking lock file %s: %m", DBLOCK);
+ return -1;
+ }
+ ptdb=dbopen(DBFIL,O_RDWR,0,DB_HASH,&info);
+ if (!ptdb) {
+ syslog(LOG_ERR, "IOERROR: opening database %s: %m", DBFIL);
+ close(fd);
+ return -1;
+ }
+ rc=PUT(ptdb,&key,&dataheader,0);
+ if (rc < 0) {
+ syslog(LOG_ERR, "IOERROR: writing database %s: %m", DBFIL);
+ CLOSE(ptdb);
+ close(fd);
+ return -1;
+ }
+ /* store the grouplist */
+ indata[key.size-4]='D';
+ rc=PUT(ptdb,&key,&datalist,0);
+ if (rc < 0) {
+ syslog(LOG_ERR, "IOERROR: writing database %s: %m", DBFIL);
+ CLOSE(ptdb);
+ close(fd);
+ return -1;
+ }
+ CLOSE(ptdb);
+ close(fd);
+ /* and we're done */
+ free(list);
+#ifdef DEBUG
+ printf("Ptclient suceeded\n");
+#endif
+
+ exit(0);
+}
+
+int fatal(char *msg, int exitcode) {
+ syslog(LOG_ERR,"%s", msg);
+ exit(-1);
+}
+
+
diff --git a/ptclient/test.c b/ptclient/test.c
new file mode 100644
index 000000000..605ca9823
--- /dev/null
+++ b/ptclient/test.c
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <sys/syslog.h>
+int main(int argc, char **argv) {
+ char *cacheid;
+ char cache[16];
+
+ if (argc < 3 || argc > 4) {
+ printf("Usage: pttset user group [cachearg]\n");
+ exit(1);
+ }
+ if (argc == 4) {
+ memset(cache,0,16);
+ strncpy(cache,argv[3],16);
+ cacheid=cache;
+ } else
+ cacheid=NULL;
+ openlog("pttest", LOG_PID,LOG_LOCAL6);
+
+ if (!auth_setid(argv[1],cacheid))
+ printf ("Auth_memberof(%s,%s) is %d\n", argv[1], argv[2],
+ auth_memberof(argv[2]));
+
+ else
+ printf ("Auth_setid(%s) failed\n", argv[1]);
+
+}
+
+int fatal(char *foo) {
+ fprintf(stderr, "Fatal error: %s\n", foo);
+ exit(1);
+}
diff --git a/ptclient/test2.c b/ptclient/test2.c
new file mode 100644
index 000000000..3f4958cea
--- /dev/null
+++ b/ptclient/test2.c
@@ -0,0 +1,20 @@
+#include <stdio.h>
+#include <sys/syslog.h>
+
+int main(void) {
+ char cacheid[16]="4224423";
+ openlog("testr", LOG_PID,LOG_LOCAL6);
+
+ if (!auth_setid("cg2v@club.cc.cmu.edu",cacheid))
+ printf ("Auth_memberof(cg2v,cg2v:me) is %d\n",
+ auth_memberof("cg2v:me"));
+
+ else
+ printf ("Auth_setid(cg2v@club.cc.cmu.edu) failed\n");
+
+}
+
+int fatal(char *foo) {
+ fprintf(stderr, "Fatal error: %s\n", foo);
+ exit(1);
+}

File Metadata

Mime Type
text/x-diff
Expires
Fri, Apr 24, 1:23 PM (1 d, 17 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18894948
Default Alt Text
(30 KB)

Event Timeline