Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F120835916
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
30 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
R111 cyrus-imapd
Attached
Detach File
Event Timeline