1/***************************************************************************
2 * LPRng - An Extended Print Spooler System
3 *
4 * Copyright 1988-2003, Patrick Powell, San Diego, CA
5 *     papowell@lprng.com
6 * See LICENSE for conditions of use.
7 *
8 ***************************************************************************/
9
10 static char *const _id =
11"$Id: sserver.c,v 1.1.1.1 2008/10/15 03:28:26 james26_jang Exp $";
12
13/*
14 *
15 * Simple authentictor test for kerberos.
16 *  Based on the SSERVER code in the Kerberos5 distibution.
17 *  See Copyrights, etc.
18 */
19
20#include "lp.h"
21#include "krb5_auth.h"
22#include "child.h"
23#include "fileopen.h"
24
25char *msg[] = {
26	"[-D options] [-p port] [-s service] [-S keytab] file",
27	"  -D turns debugging on",
28	0
29};
30
31char *progname;
32
33void
34usage()
35{
36	int i;
37	FPRINTF(STDOUT, "usage: %s %s\n", progname, msg[0]);
38	for( i = 1; msg[i]; ++i ){
39		FPRINTF(STDOUT, "%s\n", msg[i]);
40	}
41}
42
43
44
45int
46main(int argc, char *argv[])
47{
48	struct sockaddr_in peername;
49	int namelen = sizeof(peername);
50	int sock = -1;          /* incoming connection fd */
51	short port = 1234;     /* If user specifies port */
52	extern int opterr, optind, getopt(), atoi();
53	extern char * optarg;
54	int ch, fd = -1, len;
55	int on = 1;
56	int acc;
57	struct sockaddr_in sin;
58	char auth[128];
59	char *client = 0;
60	char err[128];
61	char *file;
62	char buffer[SMALLBUFFER];
63	struct stat statb;
64
65	progname = argv[0];
66	setlinebuf(STDOUT);
67
68	/*
69	 * Parse command line arguments
70	 *
71	 */
72	opterr = 0;
73	while ((ch = getopt(argc, argv, "D:p:S:s:")) != EOF)
74	switch (ch) {
75	case 'D': Parse_debug(optarg,1); break;
76	case 'p': port = atoi(optarg); break;
77	case 's': Set_DYN(&Kerberos_service_DYN,optarg); break;
78	case 'S': Set_DYN(&Kerberos_keytab_DYN,optarg); break;
79	default: usage(); exit(1); break;
80	}
81	Spool_file_perms_DYN = 0600;
82
83	if( argc - optind != 1 ){
84		usage();
85		exit(1);
86	}
87	file = argv[optind++];
88
89	if( Kerberos_keytab_DYN == 0 ) Set_DYN(&Kerberos_keytab_DYN, "/etc/lpd.keytab");
90	if( Kerberos_service_DYN == 0 ) Set_DYN(&Kerberos_service_DYN,"lpr");
91	if( port == 0 ){
92		FPRINTF( STDOUT, "bad port specified\n" );
93		exit(1);
94	}
95	/*
96	 * If user specified a port, then listen on that port; otherwise,
97	 * assume we've been started out of inetd.
98	 */
99
100	remote_principal_krb5( Kerberos_service_DYN, 0, auth, sizeof(auth));
101	FPRINTF(STDOUT, "server principal '%s'\n", auth );
102
103	if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
104		FPRINTF(STDOUT, "socket: %s\n", Errormsg(errno));
105		exit(3);
106	}
107#ifdef WINDOW_1
108int windowsize=1024;
109setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&windowsize, sizeof(windowsize));
110aaaaaa=fopen("/tmp/qqqqq", "a");
111fprintf(aaaaaa, "sserver: main\n");
112fclose(aaaaaa);
113#endif
114	Max_open(sock);
115	/* Let the socket be reused right away */
116	(void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on,
117			  sizeof(on));
118
119	memset(&sin, 0, sizeof(sin));
120	sin.sin_family = AF_INET;
121	sin.sin_addr.s_addr = 0;
122	sin.sin_port = htons(port);
123	if (bind(sock, (struct sockaddr *) &sin, sizeof(sin))) {
124		FPRINTF(STDOUT, "bind: %s\n", Errormsg(errno));
125		exit(3);
126	}
127	if (listen(sock, 1) == -1) {
128		FPRINTF(STDOUT, "listen: %s", Errormsg(errno));
129		exit(3);
130	}
131	while(1){
132		if ((acc = accept(sock, (struct sockaddr *)&peername,
133				&namelen)) == -1){
134			FPRINTF(STDOUT, "accept: %s\n", Errormsg(errno));
135			exit(3);
136		}
137
138		err[0] = 0;
139		auth[0] = 0;
140		client = 0;
141		if( server_krb5_auth( Kerberos_keytab_DYN, Kerberos_service_DYN, acc,
142			&client, err, sizeof(err), file ) ){
143			FPRINTF( STDOUT, "server_krb5_auth error '%s'\n", err );
144			goto done;
145		}
146		SNPRINTF(buffer,sizeof(buffer))"client '%s'", client );
147		FPRINTF(STDOUT,"%s\n",buffer);
148		fd = Checkread( file, &statb );
149		DEBUG1( "main: opened for write '%s', fd %d, size %ld",
150			file, fd, (long)(statb.st_size) );
151		if( fd < 0 ){
152			SNPRINTF( err, sizeof(err))
153				"file open failed: %s", Errormsg(errno));
154			goto done;
155		}
156		FPRINTF(STDOUT,"RECEVIED:\n");
157		while( (len = read(fd, buffer,sizeof(buffer)-1)) > 0 ){
158			write(1,buffer,len);
159		}
160		close(fd);
161		fd = Checkwrite( file, &statb, O_WRONLY|O_TRUNC, 1, 0 );
162		if( fd < 0 ){
163			SNPRINTF( err, sizeof(err))
164				"main: could not open for writing '%s' - '%s'", file,
165					Errormsg(errno) );
166			goto done;
167		}
168		SNPRINTF(buffer,sizeof(buffer))"credentials '%s'\n", client );
169		Write_fd_str(fd,buffer);
170		close(fd);
171		if( server_krb5_status( acc, err, sizeof(err), file ) ){
172			FPRINTF( STDOUT, "server_krb5_status error '%s'\n", err );
173			goto done;
174		}
175 done:
176		close(acc);
177	}
178	exit(0);
179}
180
181/* VARARGS2 */
182#ifdef HAVE_STDARGS
183void setstatus (struct job *job,char *fmt,...)
184#else
185void setstatus (va_alist) va_dcl
186#endif
187{
188#ifndef HAVE_STDARGS
189    struct job *job;
190    char *fmt;
191#endif
192	char msg[LARGEBUFFER];
193    VA_LOCAL_DECL
194
195    VA_START (fmt);
196    VA_SHIFT (job, struct job * );
197    VA_SHIFT (fmt, char *);
198
199	msg[0] = 0;
200	if( Verbose ){
201		(void) VSNPRINTF( msg, sizeof(msg)-2) fmt, ap);
202		strcat( msg,"\n" );
203		if( Write_fd_str( 2, msg ) < 0 ) cleanup(0);
204	}
205	VA_END;
206	return;
207}
208
209void send_to_logger( int sfd, int mfd, struct job *job, const char *header, char *msg ){;}
210/* VARARGS2 */
211#ifdef HAVE_STDARGS
212void setmessage (struct job *job,const char *header, char *fmt,...)
213#else
214void setmessage (va_alist) va_dcl
215#endif
216{
217#ifndef HAVE_STDARGS
218    struct job *job;
219    char *fmt, *header;
220#endif
221	char msg[LARGEBUFFER];
222    VA_LOCAL_DECL
223
224    VA_START (fmt);
225    VA_SHIFT (job, struct job * );
226    VA_SHIFT (header, char * );
227    VA_SHIFT (fmt, char *);
228
229	msg[0] = 0;
230	if( Verbose ){
231		(void) VSNPRINTF( msg, sizeof(msg)-2) fmt, ap);
232		strcat( msg,"\n" );
233		if( Write_fd_str( 2, msg ) < 0 ) cleanup(0);
234	}
235	VA_END;
236	return;
237}
238
239