Esempio n. 1
0
int test_chooser( struct line_list *servers,
	struct line_list *available, int *use_subserver )
{
	struct line_list *sp;
	char *s, *t, *pr;
	int i, n = -1;

	DEBUG1("test_chooser:  servers %d, available %d",
		servers->count, available->count );
	for( i = 0; i < available->count; ++i ){
 		s = available->list[i];
		DEBUG1("test_chooser: avail[%d]='%s'", i, s );
		if( (t = safestrpbrk(s,Value_sep)) ){
			n = strtol(t+1,0,0);
			DEBUG1("test_chooser: '%s' index '%d'", s, n );
			sp = (void *)servers->list[n];
			pr = Find_str_value(sp,PRINTER,Value_sep);
			DEBUG1("test_chooser: available '%s'", pr );
			if( i == 0 ){
				*use_subserver = n;
			}
		}
	}
	return( 0 );
}
Esempio n. 2
0
int Check_secure_perms( struct line_list *options, int from_server,
	char *error, int errlen )
{
	/*
	 * line 1 - CLIENT=xxxx   - client authentication
	 * line 2 - SERVER=xxxx   - server authentication
	 * ...    - FROM=xxxx     - from
	 * line 3 - INPUT=\00x  - command line
	 */
	char *authfrom, *authuser;
	authfrom = Find_str_value(options,AUTHFROM);
	if( !authfrom ) authfrom = Find_str_value(options,FROM);
	authuser = Find_str_value(options,AUTHUSER);
	if( !from_server ){
		if( !authuser && authfrom ) authuser = authfrom;
	}
	if( !authuser ) authuser = Find_str_value(options,CLIENT);
	Set_str_value(options, AUTHTYPE, Perm_check.authtype );
	Set_str_value(options, AUTHFROM, authfrom );
	Set_str_value(options, AUTHUSER, authuser );
	Perm_check.authfrom = Find_str_value(options,AUTHFROM);
	Perm_check.authuser = authuser = Find_str_value(options,AUTHUSER);
	if( !authuser ){
		plp_snprintf( error, errlen, "Printer %s@%s: missing authentication client id",
			Printer_DYN,Report_server_as_DYN?Report_server_as_DYN:ShortHost_FQDN );
		return( JABORT );
	}
	Perm_check.authca = Find_str_value(options,AUTHCA);
	DEBUGFC(DRECV1)Dump_line_list("Check_secure_perms - after",options);
	DEBUGFC(DRECV1)Dump_perm_check( "Check_secure_perms - checking", &Perm_check );
	return(0);
}
Esempio n. 3
0
 void send_to_logger( int send_to_status_fd, int send_to_mail_fd,
	struct job *job, const char *header, char *msg_b )
{
	char *s, *t;
	char *id, *tstr;
	int num,pid;
	char out_b[4*SMALLBUFFER];
	struct line_list l;

	if( !Is_server || Doing_cleanup ) return;
	Init_line_list(&l);
	if(DEBUGL4){
		char buffer[32];
		plp_snprintf(buffer,sizeof(buffer)-5, "%s", msg_b );
		if( msg_b ) safestrncat( buffer,"...");
		LOGDEBUG("send_to_logger: Logger_fd fd %d, send_to_status_fd %d, send_to_mail fd %d, header '%s', body '%s'",
			Logger_fd, send_to_status_fd, send_to_mail_fd, header, buffer );
	}
	if( send_to_status_fd <= 0 && send_to_mail_fd <= 0 && Logger_fd <= 0 ) return;
	s = t = id = tstr = 0;
	num = 0;
	if( job ){
		Set_str_value(&l,IDENTIFIER,
			(id = Find_str_value(&job->info,IDENTIFIER)) );
		Set_decimal_value(&l,NUMBER,
			(num = Find_decimal_value(&job->info,NUMBER)) );
	}
	Set_str_value(&l,UPDATE_TIME,(tstr=Time_str(0,0)));
	Set_decimal_value(&l,PROCESS,(pid=getpid()));

	plp_snprintf( out_b, sizeof(out_b), "%s at %s ## %s=%s %s=%d %s=%d\n",
		msg_b, tstr, IDENTIFIER, id, NUMBER, num, PROCESS, pid );

	if( send_to_status_fd > 0 && Write_fd_str( send_to_status_fd, out_b ) < 0 ){
		DEBUG4("send_to_logger: write to send_to_status_fd %d failed - %s",
			send_to_status_fd, Errormsg(errno) );
	}
	if( send_to_mail_fd > 0 && Write_fd_str( send_to_mail_fd, out_b ) < 0 ){
		DEBUG4("send_to_logger: write to send_to_mail_fd %d failed - %s",
			send_to_mail_fd, Errormsg(errno) );
	}
	if( Logger_fd > 0 ){
		Set_str_value(&l,PRINTER,Printer_DYN);
		Set_str_value(&l,HOST,FQDNHost_FQDN);
		s = Escape(msg_b,1);
		Set_str_value(&l,VALUE,s);
		if(s) free(s); s = 0;
		t = Join_line_list(&l,"\n");
		s = Escape(t,1); 
		if(t) free(t); t = 0;
		t = safestrdup4(header,"=",s,"\n",__FILE__,__LINE__);
		Write_fd_str( Logger_fd, t );
		if( s ) free(s); s = 0;
		if( t ) free(t); t = 0;
	}
	Free_line_list(&l);
}
Esempio n. 4
0
int Send_auth_transfer( int *sock, int transfer_timeout,
	struct job *job, struct job *logjob, char *error, int errlen, char *cmd,
	struct security *security, struct line_list *info )
{
	struct stat statb;
	int ack, len, n, fd;		/* ACME! The best... */
	int status = JFAIL;			/* job status */
	char *secure, *destination, *from, *client, *s;
	char *tempfile;
	char buffer[SMALLBUFFER];
	errno = 0;

	secure = 0;
	fd = Make_temp_fd(&tempfile);

	if( cmd && (s = safestrrchr(cmd,'\n')) ) *s = 0;
	DEBUG1("Send_auth_transfer: cmd '%s'", cmd );

	if(DEBUGL1)Dump_line_list("Send_auth_transfer: info ", info );

	destination = Find_str_value(info, DESTINATION, Value_sep );
	from = Find_str_value(info, FROM, Value_sep );
	client = Find_str_value(info, CLIENT, Value_sep );

	if( safestrcmp(security->config_tag, "kerberos") ){
		Put_in_auth(fd,DESTINATION,destination);
		if( Is_server ) Put_in_auth(fd,SERVER,from);
		Put_in_auth(fd,CLIENT,client);
		if( cmd ){
			Put_in_auth(fd,INPUT,cmd);
		}
	} else {
		if( cmd && (Write_fd_str(fd,cmd) < 0 || Write_fd_str(fd,"\n") < 0) ){
			SNPRINTF(error, errlen) "Send_auth_transfer: '%s' write failed - %s",
				tempfile, Errormsg(errno) );
			goto error;
		}
		if( Is_server && (Write_fd_str(fd,client) < 0 || Write_fd_str(fd,"\n") < 0) ){
			SNPRINTF(error, errlen) "Send_auth_transfer: '%s' write failed - %s",
				tempfile, Errormsg(errno) );
			goto error;
		}
Esempio n. 5
0
/*************************************************************************
 * Receive_secure() - receive a secure transfer
 *************************************************************************/
int Receive_secure( int *sock, char *input )
{
	char *printername;
	char error[SMALLBUFFER];	/* error message */
	char *authtype;
	char *cf, *s;
	char *jobsize = 0;
	char *user = 0;
	int tempfd = -1;
	int ack, status, from_server;
	struct line_list args, header_info, info;
	struct stat statb;
	char *tempfile = 0;
	const struct security *security = 0;

	Name = "RCVSEC";
	memset( error, 0, sizeof(error));
	ack = 0;
	status = 0;

	DEBUGF(DRECV1)("Receive_secure: input line '%s'", input );
	Init_line_list( &args );
	Init_line_list( &header_info );
	Init_line_list( &info );

	Split(&args,input+1,Whitespace,0,0,0,0,0,0);
	DEBUGFC(DRECV1)Dump_line_list("Receive_secure - input", &args);
	if( args.count != 5 && args.count != 4 ){
		plp_snprintf( error+1, sizeof(error)-1,
			_("bad command line '%s'"), input );
		ack = ACK_FAIL;	/* no retry, don't send again */
		status = JFAIL;
		goto error;
	}
	Check_max(&args,1);
	args.list[args.count] = 0;

	/*
     * \REQ_SECUREprintername C/F user authtype jobsize\n - receive a job
     *              0           1   2  3        4
	 */
	printername = args.list[0];
	cf = args.list[1];
	user = args.list[2];	/* user is escape encoded */
	Unescape(user);
	authtype = args.list[3];
	Unescape(authtype);
	jobsize = args.list[4];

	setproctitle( "lpd %s '%s'", Name, printername );

	Perm_check.authtype = authtype;
	from_server = 0;
	if( *cf == 'F' ){
		from_server = 1;
	}

	/* set up the authentication support information */

	if( Is_clean_name( printername ) ){
		plp_snprintf( error+1, sizeof(error)-1,
			_("bad printer name '%s'"), input );
		ack = ACK_FAIL;	/* no retry, don't send again */
		status = JFAIL;
		goto error;
	}

	Set_DYN(&Printer_DYN,printername);

	if( Setup_printer( printername, error+1, sizeof(error)-1, 0 ) ){
		if( jobsize ){
			plp_snprintf( error+1, sizeof(error)-1,
				_("bad printer '%s'"), printername );
			ack = ACK_FAIL;	/* no retry, don't send again */
			status = JFAIL;
			goto error;
		}
	} else {
		int db, dbf;

		db = Debug;
		dbf = DbgFlag;
		s = Find_str_value(&Spool_control,DEBUG);
		if(!s) s = New_debug_DYN;
		Parse_debug( s, 0 );

		if( !(DRECVMASK & DbgFlag) ){
			Debug = db;
			DbgFlag = dbf;
		} else {
			int tdb, tdbf;
			tdb = Debug;
			tdbf = DbgFlag;
			Debug = db;
			DbgFlag = dbf;
			if( Log_file_DYN ){
				tempfd = Checkwrite( Log_file_DYN, &statb,0,0,0);
				if( tempfd > 0 && tempfd != 2 ){
					dup2(tempfd,2);
					close(tempfd);
				}
				tempfd = -1;
			}
			Debug = tdb;
			DbgFlag = tdbf;
			LOGDEBUG("Receive_secure: socket fd %d", *sock);
			Dump_line_list("Receive_secure - input", &args);
		}
		DEBUGF(DRECV1)("Receive_secure: debug '%s', Debug %d, DbgFlag 0x%x",
			s, Debug, DbgFlag );
	}

	if( !(security = Fix_receive_auth(authtype, &info)) ){
		plp_snprintf( error+1, sizeof(error)-1,
			_("unsupported authentication '%s'"), authtype );
		ack = ACK_FAIL;	/* no retry, don't send again */
		status = JFAIL;
		goto error;
	}
	if( !security->server_receive ){
		plp_snprintf( error+1, sizeof(error)-1,
			_("no receive method supported for '%s'"), authtype );
		ack = ACK_FAIL;	/* no retry, don't send again */
		status = JFAIL;
		goto error;
	}


	if( jobsize ){
		double read_len;
		read_len = strtod(jobsize,0);

		DEBUGF(DRECV2)("Receive_secure: spooling_disabled %d",
			Sp_disabled(&Spool_control) );
		if( Sp_disabled(&Spool_control) ){
			plp_snprintf( error+1, sizeof(error)-1,
				_("%s: spooling disabled"), Printer_DYN );
			ack = ACK_RETRY;	/* retry */
			status = JFAIL;
			goto error;
		}
		if( Max_job_size_DYN > 0 && (read_len+1023)/1024 > Max_job_size_DYN ){
			plp_snprintf( error+1, sizeof(error)-1,
				_("%s: job size %0.0f is larger than %d K"),
				Printer_DYN, read_len, Max_job_size_DYN );
			ack = ACK_RETRY;
			status = JFAIL;
			goto error;
		} else if( !Check_space( read_len, Minfree_DYN, Spool_dir_DYN ) ){
			plp_snprintf( error+1, sizeof(error)-1,
				_("%s: insufficient file space"), Printer_DYN );
			ack = ACK_RETRY;
			status = JFAIL;
			goto error;
		}
	}

	tempfd = Make_temp_fd(&tempfile);
	close(tempfd); tempfd = -1;

	DEBUGF(DRECV1)("Receive_secure: sock %d, user '%s', jobsize '%s'",  
		*sock, user, jobsize );

	status = security->server_receive( sock, Send_job_rw_timeout_DYN,
		user, jobsize, from_server, authtype,
		&info,
		error+1, sizeof(error)-1,
		&header_info,
		security, tempfile, Do_secure_work);

 error:
	DEBUGF(DRECV1)("Receive_secure: status %d, ack %d, error '%s'",
		status, ack, error+1 );

	if( status ){
		if( ack == 0 ) ack = ACK_FAIL;
		error[0] = ack;
		DEBUGF(DRECV1)("Receive_secure: sending '%s'", error );
		(void)Link_send( ShortRemote_FQDN, sock,
			Send_query_rw_timeout_DYN, error, safestrlen(error), 0 );
		Errorcode = JFAIL;
	}

	Free_line_list( &args );
	Free_line_list( &header_info );
	Free_line_list( &info );

	close( *sock ); *sock = -1;
	Remove_tempfiles();

	if( status == 0 && jobsize ){
		/* start a new server */
		DEBUGF(DRECV1)("Receive_secure: starting server");
		if( Server_queue_name_DYN ){
			Do_queue_jobs( Server_queue_name_DYN, 0 );
		} else {
			Do_queue_jobs( Printer_DYN, 0 );
		}
	}
	cleanup(0);
}
Esempio n. 6
0
static int Do_secure_work( char *jobsize, int from_server,
	char *tempfile, struct line_list *header_info )
{
	int n, len, linecount = 0, done = 0, fd, status = 0;
	char *s, *t;
	char buffer[SMALLBUFFER];
	char error[SMALLBUFFER];
	struct stat statb;

	error[0] = 0;
	if( (fd = Checkread(tempfile,&statb)) < 0 ){ 
		status = JFAIL;
		plp_snprintf( error, sizeof(error),
			"Do_secure_work: reopen of '%s' failed - %s",
				tempfile, Errormsg(errno));
		goto error;
	}

	buffer[0] = 0;
	n = 0;
	done = 0;
	linecount = 0;

	while( !done && n < (int)sizeof(buffer)-1
		&& (len = Read_fd_len_timeout( Send_query_rw_timeout_DYN, fd, buffer+n, sizeof(buffer)-1-n )) > 0 ){
		buffer[n+len] = 0;
		DEBUGF(DRECV1)("Do_secure_work: read %d - '%s'", len, buffer );
		while( !done && (s = safestrchr(buffer,'\n')) ){
			*s++ = 0;
			if( safestrlen(buffer) == 0 ){
				done = 1;
				break;
			}
			DEBUGF(DRECV1)("Do_secure_work: line [%d] '%s'", linecount, buffer );
			if( (t = strchr(buffer,'=')) ){
				*t++ = 0;
				Unescape(t);
				Set_str_value(header_info, buffer, t );
			} else {
				switch( linecount ){
					case 0:
						if( jobsize ){
							if( from_server ){
								Set_str_value(header_info,CLIENT,buffer);
							}
							done = 1;
						} else {
							Set_str_value(header_info,INPUT,buffer); break;
						}
						break;
					case 1:
						Set_str_value(header_info,CLIENT,buffer);
						done = 1;
						break;
				}
			}
			++linecount;
			memmove(buffer,s,safestrlen(s)+1);
			n = safestrlen(buffer);
		}
	}

	if( fd >= 0 ) close(fd); fd = -1;

	DEBUGFC(DRECV1)Dump_line_list("Do_secure_work - header", header_info );

	if( (status = Check_secure_perms( header_info, from_server, error, sizeof(error))) ){
		goto error;
	}
	DEBUGFC(DRECV1)Dump_line_list("Do_secure_work - header after check", header_info );


	buffer[0] = 0;
	if( jobsize ){
		if( (fd = Checkread(tempfile, &statb) ) < 0 ){
			status = JFAIL;
			plp_snprintf( error, sizeof(error),
				"Do_secure_work: reopen of '%s' for read failed - %s",
					tempfile, Errormsg(errno));
			goto error;
		}
		status = Scan_block_file( fd, error, sizeof(error), header_info );
		if( (fd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0 ){
			status = JFAIL;
			plp_snprintf( error, sizeof(error),
				"Do_secure_work: reopen of '%s' for write failed - %s",
					tempfile, Errormsg(errno));
			goto error;
		}
	} else {
		if( (fd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0 ){
			status = JFAIL;
			plp_snprintf( error, sizeof(error),
				"Do_secure_work: reopen of '%s' for write failed - %s",
					tempfile, Errormsg(errno));
			goto error;
		}
		if( (s = Find_str_value(header_info,INPUT)) ){
			Dispatch_input( &fd, s, "from secure link" );
		}
	}

 error:

	if( fd >= 0 ) close(fd); fd = -1;
	DEBUGF(DRECV1)("Do_secure_work: status %d, tempfile '%s', error '%s'",
		status, tempfile, error );
	if( error[0] ){
		DEBUGF(DRECV1)("Do_secure_work: updating tempfile '%s', error '%s'",
			tempfile, error );
		if( (fd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0 ){
			Errorcode = JFAIL;
			logerr_die(LOG_INFO, "Do_secure_work: reopen of '%s' for write failed",
				tempfile );
		}
		Write_fd_str(fd,error);
		close(fd);
	}
	DEBUGF(DRECV1)("Do_secure_work: returning %d", status );
	return( status );
}
Esempio n. 7
0
void Decode( char *in )
{
	struct line_list l, cf, info;
	char *s, *t, *header, *value;
	int i;

	Init_line_list(&l);
	Init_line_list(&cf);
	Init_line_list(&info);

	FPRINTF(STDOUT,"****\n");
	if( debug )FPRINTF(STDOUT, "Decode: %s\n", in );
	if((s = safestrpbrk(in,Value_sep)) ){
		*s++ = 0;
		Unescape(s);
		Free_line_list(&l);
		Split(&l,s,Line_ends,1,Value_sep,1,1,1,0);
		for( i = 0; i < l.count; ++i ){
			t = l.list[i];
			if( debug || safestrncasecmp(t,VALUE,5) ){
				FPRINTF(STDOUT,"%s\n", t );
			}
		}
		s = Find_str_value(&l,VALUE,Value_sep);
		if( s ) Unescape(s);
		if( !safestrcasecmp(in,TRACE) ){
			FPRINTF(STDOUT,"TRACE: '%s'\n", s );
		} else if( !safestrcasecmp(in,UPDATE) ){
			FPRINTF(STDOUT,"UPDATE: '%s'\n", s );
			Split(&info,s,Line_ends,0,0,0,0,0,0);
			for( i = 0; i < info.count; ++i ){
				header = info.list[i];
				if( (value = safestrchr(header,'=')) ) *value++ = 0;
				Unescape(value);
				FPRINTF(STDOUT," [%d] %s='%s'\n", i, header, value );
			}
		} else if( !safestrcasecmp(in,PRSTATUS) ){
			FPRINTF(STDOUT,"PRSTATUS: '%s'\n", s );
		} else if( !safestrcasecmp(in,QUEUE) ){
			FPRINTF(STDOUT,"QUEUE: '%s'\n", s );
			Split(&info,s,Line_ends,0,0,0,0,0,0);
			for( i = 0; i < info.count; ++i ){
				header = info.list[i];
				if( (value = safestrchr(header,'=')) ) *value++ = 0;
				Unescape(value);
				FPRINTF(STDOUT," [%d] %s='%s'\n", i, header, value );
			}
			Free_line_list(&info);
		} else if( !safestrcasecmp(in,DUMP) ){
			FPRINTF(STDOUT,"DUMP:\n");
			Split(&info,s,Line_ends,0,0,0,0,0,0);
			for( i = 0; i < info.count; ++i ){
				header = info.list[i];
				if( (value = safestrchr(header,'=')) ) *value++ = 0;
				Unescape(value);
				if(debug) FPRINTF(STDOUT," [%d] %s='%s'\n", i, header, value );
				if( !safestrcasecmp(header,QUEUE) ){
					FPRINTF(STDOUT," EXTRACT QUEUE '%s'\n",value);
				} else if( !safestrcasecmp(header,UPDATE) ){
					FPRINTF(STDOUT," EXTRACT UPDATE '%s'\n",value);
				} else {
					FPRINTF(STDOUT," EXTRACT '%s' '%s'\n",header, value);
				}
			}
			Free_line_list(&info);
		} else {
			FPRINTF(STDOUT,"%s: '%s'\n", in, s );
		}
	}
	Free_line_list(&l);
	Free_line_list(&cf);
	Free_line_list(&info);
	FPRINTF(STDOUT,"\n");
}