home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1990 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-
- #include "dixie.h"
- #include <stdio.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/time.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <sys/syslog.h>
- #include <sys/wait.h>
- #include <signal.h>
-
- #ifndef FD_SET
- #define NFDBITS 32
- #define FD_SETSIZE 32
- #define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
- #define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
- #define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
- #define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
- #endif
-
- /*#define DAPUSER "c=US@o=University of Minnesota@ou=Miscellaneous Servers@cn=Go500"*/
- #define DAPUSER NULL
- #define DEFAULT_BASE "c=US@o=University of Minnesota"
- #define DEFAULT_DIXIEHOST "x500.tc.umn.edu"
- #define DEFAULT_GO500PORT 5555
-
- int debug;
- int dosyslog;
-
- char *dixiehost = DEFAULT_DIXIEHOST;
- char *base = DEFAULT_BASE;
- int strip = 3;
- int searchaliases = 1;
-
- char *myhost = "mudhoney.micro.umn.edu";
- int myport;
-
- static usage( name )
- char *name;
- {
- fprintf( stderr, "usage: %s [-d debuglevel] [-p port] [-l] [-x dixiehost] [-b searchbase] [-a]\n" );
- exit( 1 );
- }
-
- main (argc, argv)
- int argc;
- char **argv;
- {
- int s, ns, rc;
- int port = -1;
- int tblsize;
- int i, pid;
- char *myname;
- fd_set readfds;
- struct hostent *hp;
- struct sockaddr_in from;
- int fromlen;
- int wait4child();
- extern char *optarg;
-
- while ( (i = getopt( argc, argv, "ab:d:lp:s:x:" )) != EOF ) {
- switch( i ) {
- case 'a':
- searchaliases = 0;
- break;
-
- case 'b':
- base = strdup( optarg );
- break;
-
- case 'd':
- debug = atoi( optarg );
- break;
-
- case 'l':
- dosyslog = 1;
- break;
-
- case 'p':
- port = atoi( optarg );
- break;
-
- case 's':
- strip = atoi( optarg );
- break;
-
- case 'x':
- dixiehost = strdup( optarg );
- break;
-
- default:
- usage( argv[0] );
- }
- }
-
- /* detach if stderr is redirected or no debugging */
- (void) detach( debug );
-
- if ( (myname = strrchr( argv[0], '/' )) == NULL )
- myname = strdup( argv[0] );
- else
- myname = strdup( myname + 1 );
-
- if ( dosyslog && openlog( myname, LOG_PID | LOG_NOWAIT, LOG_LOCAL3 )
- < 0 ) {
- perror("openlog");
- }
- if ( dosyslog ) syslog( LOG_INFO, "initializing" );
-
- /* set up the socket to listen on */
- s = set_socket( port );
-
- /* arrange to reap children */
- (void) signal( SIGCHLD, wait4child );
-
- tblsize = getdtablesize();
- for ( ;; ) {
- FD_ZERO( &readfds );
- FD_SET( s, &readfds );
-
- if ( (rc = select( tblsize, &readfds, 0, 0 ,0 )) == -1 ) {
- if ( debug ) perror( "select" );
- continue;
- } else if ( rc == 0 ) {
- continue;
- }
-
- if ( ! FD_ISSET( s, &readfds ) )
- continue;
-
- fromlen = sizeof(from);
- if ( (ns = accept( s, &from, &fromlen )) == -1 ) {
- if ( debug ) perror( "accept" );
- exit( 1 );
- }
-
- hp = gethostbyaddr( (char *) &(from.sin_addr.s_addr),
- sizeof(from.sin_addr.s_addr), AF_INET );
- syslog( LOG_INFO, "TCP connection from %s (%s)",
- (hp == NULL) ? "unknown" : hp->h_name,
- inet_ntoa( from.sin_addr ) );
-
- switch( pid = fork() ) {
- case 0: /* child */
- close( s );
- do_queries( ns );
- break;
-
- case -1: /* failed */
- perror( "fork" );
- break;
-
- default: /* parent */
- close( ns );
- if ( debug )
- fprintf( stderr, "forked child %d\n", pid );
- break;
- }
- }
- /* NOT REACHED */
- }
-
- static set_socket( port )
- int port;
- {
- int s;
- struct sockaddr_in addr;
-
- if ( port == -1 )
- port = DEFAULT_GO500PORT;
- myport = port;
-
- if ( (s = socket( AF_INET, SOCK_STREAM, 0 )) == -1 ) {
- perror( "socket" );
- exit( 1 );
- }
-
- /* set option so clients can't keep us from coming back up */
- if ( setsockopt( s, SOL_SOCKET, SO_REUSEADDR, 0, 0 ) < 0 ) {
- perror( "setsockopt" );
- exit( 1 );
- }
-
- /* bind to a name */
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
- addr.sin_port = htons( port );
- if ( bind( s, &addr, sizeof(addr) ) ) {
- perror( "bind" );
- exit( 1 );
- }
-
- /* listen for connections */
- if ( listen( s, 5 ) == -1 ) {
- perror( "listen" );
- exit( 1 );
- }
-
- if ( debug ) printf("tcp socket allocated, bound, and listening\n");
-
- return( s );
- }
-
- static wait4child()
- {
- #if defined(SunOS) && SunOS < 40
- union wait status;
- #else
- int status;
- #endif
-
- if ( debug ) printf( "parent: catching child status\n" );
- while ( wait3( &status, WNOHANG | WUNTRACED, 0 ) > 0 )
- ; /* NULL */
- }
-
- static char dixie_buffer[MAX_PKT_SIZE];
-
- static do_queries( s )
- int s;
- {
- char buf[256];
- int len;
- FILE *fp;
- int rc, tblsize;
- struct timeval timeout;
- fd_set readfds;
-
- if ( dxi_init( dixiehost, 0, 0 ) == -1 ) {
- if ( debug ) perror( "dxi_init" );
- exit( 1 );
- }
- if ( !searchaliases )
- dxi_options |= DXI_OPT_DONTSEARCHALIASES;
-
- if ( dxi_bind( DAPUSER, NULL ) == -1 ) {
- if ( debug ) dxi_perror( "dxi_bind" );
- exit( 1 );
- }
- dxi_not61 = 1;
-
- if ( (fp = fdopen( s, "a+")) == NULL ) {
- perror( "fdopen" );
- exit( 1 );
- }
-
- tblsize = getdtablesize();
- timeout.tv_sec = 300;
- timeout.tv_usec = 0;
- FD_ZERO( &readfds );
- FD_SET( fileno( fp ), &readfds );
-
- if ( (rc = select( tblsize, &readfds, 0, 0, &timeout )) <= 0 )
- exit( 1 );
-
- if ( fgets( buf, sizeof(buf), fp ) == NULL )
- exit( 1 );
-
- len = strlen( buf );
- if ( debug ) {
- fprintf( stderr, "got %d bytes\n", len );
- dxi_bprint( buf, len );
- }
-
- /* strip of \r \n */
- if ( buf[len - 1] == '\n' )
- buf[len - 1] = '\0';
- len--;
- if ( buf[len - 1] == '\r' )
- buf[len - 1] = '\0';
- len--;
-
- rewind(fp);
- if ( strchr( buf, '=' ) )
- do_read( fp, buf );
- else
- do_search( fp, buf );
- fprintf( fp, ".\r\n" );
- rewind(fp);
-
- exit( 1 );
- /* NOT REACHED */
- }
-
- static do_search( fp, buf )
- FILE *fp;
- char *buf;
- {
- char filter[1024];
- char *dn, *e, *rdn;
- char **title;
- static char *attrs[] = { "title", 0 };
-
- sprintf( filter, "uid=%s|sn=%s|cn=%s", buf, buf, buf );
-
- if ( dxi_search( base, DXI_SRCH_SUBTREE, filter, attrs, dixie_buffer )
- == -1 ) {
- dxi_perror( "dxi_search" );
- exit( 1 );
- }
-
- for ( e = dxi_firstentry( dixie_buffer ); e != NULL;
- e = dxi_nextentry() ) {
- dn = dxi_getdn( e );
- rdn = dxi_lastdncomp( dn );
- title = dxi_getvalues( e, "title" );
-
- fprintf( fp, "0%-20s %s\t%s\t%s\t%d\r\n", rdn,
- title ? title[0] : "", dn, myhost, myport );
-
- dxi_valuefree( title );
- free( dn );
- }
- }
-
- static print_attr( fp, label, attr, e, multiline )
- FILE *fp;
- char *label;
- char *attr;
- char *e;
- int multiline;
- {
- char **val;
- int i, gotone = 0, firstline = 1;
-
- if ( (val = dxi_getvalues( e, attr )) == NULL )
- return;
-
- fprintf( fp, "%-19s\r\n", label );
- for ( i = 0; val[i] != NULL; i++ ) {
- if ( multiline ) {
- char *s, *p;
-
- if ( gotone )
- fprintf( fp, "%-19s\r\n", label );
- p = s = val[i];
- while ( s = strchr( s, '$' ) ) {
- *s++ = '\0';
- while ( isspace( *s ) )
- s++;
- if ( firstline ) {
- fprintf( fp, " %s\r\n", p );
- firstline = 0;
- } else {
- fprintf( fp, " %s\r\n", p );
- }
- p = s;
- }
- if ( firstline ) {
- fprintf( fp, " %s\r\n", p );
- } else {
- fprintf( fp, " %s\r\n", p );
- }
- gotone = 1;
- firstline = 1;
- } else {
- if ( firstline ) {
- fprintf( fp, " %s\r\n", val[i] );
- firstline = 0;
- } else {
- fprintf( fp, " %s\r\n", val[i] );
- }
- }
- }
- dxi_valuefree( val );
- }
-
- static do_read( fp, buf )
- FILE *fp;
- char *buf;
- {
- char *dn, *e, *ufn;
- int i;
- char *s;
- char **cn, **paddr, **tnumber, **uid, **title, **mail;
- static char *attrs[] = { "cn", "postalAddress", "uid", "title",
- "mail", "telephoneNumber",
- "facsimileTelephoneNumber", 0 };
-
- if ( dxi_read( buf, attrs, dixie_buffer ) == -1 ) {
- if ( debug ) dxi_perror( "dxi_read" );
- exit( 1 );
- }
-
- e = dxi_getreadentry( dixie_buffer );
- dn = dxi_getdn( e );
- ufn = dxi_dn2ufn( dn );
- for ( i = 0; i < strip; i++ ) {
- if ( (s = strrchr( ufn, ',' )) == NULL )
- break;
- *s = '\0';
- }
- fprintf( fp, "\"%s\"\r\n", ufn );
- print_attr( fp, " Also known as:", "cn", e, 0 );
- print_attr( fp, " E-mail address:", "mail", e, 0 );
- print_attr( fp, " Fax number:", "facsimileTelephoneNumber", e, 0 );
- print_attr( fp, " Business phone:", "telephoneNumber", e, 0 );
- print_attr( fp, " Business address:", "postalAddress", e, 1 );
- print_attr( fp, " Title:", "title", e, 0 );
- print_attr( fp, " Uniqname:", "uid", e, 0 );
-
- free( dn );
- }
-