Пример #1
0
papi_status_t
hold_release_job(papi_service_t handle, char *printer,
		int32_t job_id, int flag)
{
	papi_status_t status;
	service_t *svc = handle;
	REQUEST *r = NULL;
	char *file;
	char *dest;

	if ((svc == NULL) || (printer == NULL) || (job_id < 0))
		return (PAPI_BAD_ARGUMENT);

	if ((status = authorized(svc, job_id)) != PAPI_OK)
		return (status);

	dest = printer_name_from_uri_id(printer, job_id);
	status = lpsched_start_change(svc, dest, job_id, &file);
	if (status != PAPI_OK)
		return (status);

	if ((r = getrequest(file)) != NULL) {
		r->actions &= ~ACT_RESUME;
		switch (flag) {
		case 0:
			r->actions |= ACT_HOLD;
			break;
		case 1:
			r->actions |= ACT_RESUME;
			break;
		case 2:
			r->actions |= ACT_IMMEDIATE;
			break;
		}
		if (putrequest(file, r) < 0) {
			detailed_error(svc,
			    gettext("failed to write job: %s: %s"),
			    file, strerror(errno));
			freerequest(r);
			return (PAPI_DEVICE_ERROR);
		}
		freerequest(r);
	} else {
		detailed_error(svc, gettext("failed to read job: %s: %s"),
		    file, strerror(errno));
		return (PAPI_DEVICE_ERROR);
	}

	status = lpsched_end_change(svc, dest, job_id);

	return (status);
}
Пример #2
0
void Connection::request( const char* method,
	const char* url,
	const char* headers[],
	const unsigned char* body,
	int bodysize )
{

	bool gotcontentlength = false;	// already in headers?

	// check headers for content-length
	// TODO: check for "Host" and "Accept-Encoding" too
	// and avoid adding them ourselves in putrequest()
	if( headers )
	{
		const char** h = headers;
		while( *h )
		{
			const char* name = *h++;
			const char* value = *h++;
			assert( value != 0 );	// name with no value!

			if( 0==_stricmp( name, "content-length" ) )
				gotcontentlength = true;
		}
	}

	putrequest( method, url );

	if( body && !gotcontentlength )
		putheader( "Content-Length", bodysize );

	if( headers )
	{
		const char** h = headers;
		while( *h )
		{
			const char* name = *h++;
			const char* value = *h++;
			putheader( name, value );
		}
	}
	endheaders();

	if( body )
		send( body, bodysize );

}
Пример #3
0
papi_status_t
papiJobCommit(papi_service_t handle, char *printer, int32_t id)
{
	papi_status_t status = PAPI_OK;
	service_t *svc = handle;
	REQUEST *r = NULL;
	char *metadata_file;
	char *dest;

	if ((svc == NULL) || (printer == NULL))
		return (PAPI_BAD_ARGUMENT);

	dest = printer_name_from_uri_id(printer, id);
	/* tell the scheduler that we want to change the job */
	status = lpsched_start_change(svc, dest, id, &metadata_file);
	if (status != PAPI_OK)
		return (status);

	if ((r = getrequest(metadata_file)) != NULL) {
		r->actions &= ~ACT_RESUME;
		r->actions |= ACT_RESUME;
		dellist(&r->file_list, DUMMY_FILE);

		if (putrequest(metadata_file, r) < 0) {
			detailed_error(svc,
			    gettext("failed to write job: %s: %s"),
			    metadata_file, strerror(errno));
			freerequest(r);
			return (PAPI_DEVICE_ERROR);
		}
	} else {
		detailed_error(svc, gettext("failed to read job: %s: %s"),
		    metadata_file, strerror(errno));
		return (PAPI_DEVICE_ERROR);
	}

	status = lpsched_end_change(svc, dest, id);
	freerequest(r);

	return (status);
}
Пример #4
0
papi_status_t
papiJobStreamOpen(papi_service_t handle, char *printer,
		papi_attribute_t **job_attributes,
		papi_job_ticket_t *job_ticket, papi_stream_t *stream)
{
	papi_status_t status;
	service_t *svc = handle;
	job_stream_t *s = NULL;
	char *request_id = NULL;
	char lpfile[BUFSIZ];

	if ((svc == NULL) || (printer == NULL) || (stream == NULL))
		return (PAPI_BAD_ARGUMENT);

	if (job_ticket != NULL)
		return (PAPI_OPERATION_NOT_SUPPORTED);

	if ((*stream = s = calloc(1, sizeof (*s))) == NULL)
		return (PAPI_TEMPORARY_ERROR);

	/* 1 for data, 1 for the meta-data (-0) */
	status = lpsched_alloc_files(svc, 2, &request_id);
	if (status != PAPI_OK)
		return (status);

	s->request = create_request(svc, (char *)printer,
	    (papi_attribute_t **)job_attributes);
	snprintf(lpfile, sizeof (lpfile), "/var/spool/lp/temp/%s-1",
	    request_id);
	s->fd = open(lpfile, O_WRONLY);
	addlist(&(s->request->file_list), lpfile);

#ifdef LP_USE_PAPI_ATTR
	/*
	 * store the job attributes in the PAPI job attribute file that was
	 * created by lpsched_alloc_files(), the attributes will then pass
	 * through lpsched and be given to the slow-filters and the printer's
	 * interface script to process them
	 */
	snprintf(lpfile, sizeof (lpfile), "%s%s-%s",
	    "/var/spool/lp/temp/", request_id, LP_PAPIATTRNAME);
	status = psm_copy_attrsToFile(job_attributes, lpfile);
	if (status != PAPI_OK) {
		detailed_error(svc, "unable to copy attributes to file: %s: %s",
		    lpfile, strerror(errno));
		close(s->fd);
		free(s);
		return (PAPI_DEVICE_ERROR);
	}
#endif

	/* store the meta-data file */
	snprintf(lpfile, sizeof (lpfile), "%s-0", request_id);
	s->meta_data_file = strdup(lpfile);
	if (putrequest(lpfile, s->request) < 0) {
		detailed_error(svc, gettext("unable to save request: %s: %s"),
		    lpfile, strerror(errno));
		s->request = NULL;
		return (PAPI_DEVICE_ERROR);
	}

	return (PAPI_OK);
}
Пример #5
0
papi_status_t
papiJobSubmitByReference(papi_service_t handle, char *printer,
		papi_attribute_t **job_attributes,
		papi_job_ticket_t *job_ticket,
		char **files, papi_job_t *job)
{
	service_t *svc = handle;
	struct stat statbuf;
	job_t *j;
	int file_no;
	short status;
	char *request_id = NULL;
	REQUEST *request;
	char *c;
	char *tmp = NULL;
	char lpfile[BUFSIZ];
	char **file_list = NULL;

	if ((svc == NULL) || (printer == NULL) || (files == NULL) ||
	    (job == NULL))
		return (PAPI_BAD_ARGUMENT);

	if (job_ticket != NULL)
		return (PAPI_OPERATION_NOT_SUPPORTED);

	if (files != NULL)
		for (file_no = 0; files[file_no] != NULL; file_no++) {
			if (access(files[file_no], R_OK) < 0) {
				detailed_error(svc,
				    gettext("Cannot access file: %s: %s"),
				    files[file_no], strerror(errno));
				return (PAPI_DOCUMENT_ACCESS_ERROR);
			}
			if (stat(files[file_no], &statbuf) < 0) {
				detailed_error(svc,
				    gettext("Cannot access file: %s: %s"),
				    files[file_no], strerror(errno));
				return (PAPI_DOCUMENT_ACCESS_ERROR);
			}
			if (statbuf.st_size == 0) {
				detailed_error(svc,
				    gettext("Zero byte (empty) file: %s"),
				    files[file_no]);
				return (PAPI_BAD_ARGUMENT);
			}

			if (files[file_no][0] != '/') {
				char path[MAXPATHLEN];

				if (getcwd(path, sizeof (path)) == NULL) {
					detailed_error(svc, gettext(
					    "getcwd for file: %s: %s"),
					    files[file_no],
					    strerror(errno));
					return (PAPI_DOCUMENT_ACCESS_ERROR);
				}
				strlcat(path, "/", sizeof (path));
				if (strlcat(path, files[file_no], sizeof (path))
				    >= sizeof (path)) {
					detailed_error(svc, gettext(
					    "pathname too long: %s"),
					    files[file_no]);
					return (PAPI_DOCUMENT_ACCESS_ERROR);
				}
				addlist(&file_list, path);
			} else
				addlist(&file_list, (char *)files[file_no]);
		}

	if ((*job = j = calloc(1, sizeof (*j))) == NULL)
		return (PAPI_TEMPORARY_ERROR);

	/* 1 for the control file (-0) */
	status = lpsched_alloc_files(svc, 1, &request_id);
	if (status != PAPI_OK)
		return (status);

	request = create_request(svc, (char *)printer,
	    (papi_attribute_t **)job_attributes);
	request->file_list = file_list;

#ifdef LP_USE_PAPI_ATTR
	/*
	 * store the job attributes in the PAPI job attribute file that was
	 * created by lpsched_alloc_files(), the attributes will then pass
	 * through lpsched and be given to the slow-filters and the printer's
	 * interface script to process them
	 */
	snprintf(lpfile, sizeof (lpfile), "%s%s-%s",
	    "/var/spool/lp/temp/", request_id, LP_PAPIATTRNAME);
	status = psm_copy_attrsToFile(job_attributes, lpfile);
	if (status != PAPI_OK) {
		detailed_error(svc, "unable to copy attributes to file: %s: %s",
		    lpfile, strerror(errno));
		return (PAPI_DEVICE_ERROR);
	}
#endif

	/* store the meta-data file */
	snprintf(lpfile, sizeof (lpfile), "%s-0", request_id);
	if (putrequest(lpfile, request) < 0) {
		detailed_error(svc, gettext("unable to save request: %s: %s"),
		    lpfile, strerror(errno));
		freerequest(request);
		return (PAPI_DEVICE_ERROR);
	}

	status = lpsched_commit_job(svc, lpfile, &tmp);
	if (status != PAPI_OK) {
		unlink(lpfile);
		freerequest(request);
		return (status);
	}

	lpsched_request_to_job_attributes(request, j);

	freerequest(request);

	if ((c = strrchr(tmp, '-')) != NULL)
		c++;
	papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
	    "job-id", atoi(c));
	papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE,
	    "job-uri", tmp);

	return (PAPI_OK);
}
Пример #6
0
papi_status_t
papiJobStreamAdd(papi_service_t handle, char *printer, int32_t id,
		papi_stream_t *stream)
{
	papi_status_t status;
	service_t *svc = handle;
	job_stream_t *s = NULL;
	char *metadata_file = NULL;
	char *dest;
	char path[MAXPATHLEN];

	/* allocate space for the stream */
	if ((*stream = s = calloc(1, sizeof (*s))) == NULL)
		return (PAPI_TEMPORARY_ERROR);

	dest = printer_name_from_uri_id(printer, id);
	/* create/open data file (only root or lp can really do this */
	snprintf(path, sizeof (path), "/var/spool/lp/temp/%d-XXXXXX", id);
	if ((s->fd = mkstemp(path)) < 0) {
		detailed_error(svc, gettext("unable to create sink (%s): %s"),
		    path, strerror(errno));
		free(s);
		return (PAPI_NOT_AUTHORIZED);
	}

	/* add data file to job */
	status = lpsched_start_change(svc, dest, id, &metadata_file);
	if (status != PAPI_OK) {
		close(s->fd);
		free(s);
		unlink(path);
		return (status);
	}

	if ((s->request = getrequest(metadata_file)) == NULL) {
		detailed_error(svc, gettext("unable to load request: %s: %s"),
		    metadata_file, strerror(errno));
		close(s->fd);
		free(s);
		unlink(path);
		return (PAPI_NOT_POSSIBLE);
	}

	addlist(&(s->request->file_list), path);

	if (putrequest(metadata_file, s->request) < 0) {
		detailed_error(svc, gettext("unable to save request: %s: %s"),
		    metadata_file, strerror(errno));
		close(s->fd);
		free(s);
		unlink(path);
		return (PAPI_NOT_POSSIBLE);
	}

	status = lpsched_end_change(svc, dest, id);

	if (status != PAPI_OK)
		return (status);

	return (PAPI_OK);
}
Пример #7
0
papi_status_t
papiJobCreate(papi_service_t handle, char *printer,
		papi_attribute_t **job_attributes,
		papi_job_ticket_t *job_ticket, papi_job_t *job)
{
	papi_status_t status;
	service_t *svc = handle;
	job_t *j = NULL;
	REQUEST *request;
	char *request_id = NULL;
	char *c;
	char *tmp = NULL;
	char metadata_file[MAXPATHLEN];

	if ((svc == NULL) || (printer == NULL) || (job == NULL))
		return (PAPI_BAD_ARGUMENT);

	if (job_ticket != NULL)
		return (PAPI_JOB_TICKET_NOT_SUPPORTED);

	if ((*job = j = calloc(1, sizeof (*j))) == NULL)
		return (PAPI_TEMPORARY_ERROR);

	/* 1 for the control file (-0) */
	status = lpsched_alloc_files(svc, 1, &request_id);
	if (status != PAPI_OK)
		return (status);

	/* convert the attributes to an lpsched REQUEST structure */
	request = create_request(svc, (char *)printer,
	    (papi_attribute_t **)job_attributes);
	if (request == NULL)
		return (PAPI_TEMPORARY_ERROR);
	addlist(&request->file_list, DUMMY_FILE);	/* add a dummy file */
	request->actions |= ACT_HOLD;			/* hold the job */

#ifdef LP_USE_PAPI_ATTR
	/*
	 * store the job attributes in the PAPI job attribute file that was
	 * created by lpsched_alloc_files(), the attributes will then pass
	 * through lpsched and be given to the slow-filters and the printer's
	 * interface script to process them
	 */
	snprintf(metadata_file, sizeof (metadata_file), "%s%s-%s",
	    "/var/spool/lp/temp/", request_id, LP_PAPIATTRNAME);
	status = psm_copy_attrsToFile(job_attributes, metadata_file);
	if (status != PAPI_OK) {
		detailed_error(svc, "unable to copy attributes to file: %s: %s",
		    metadata_file, strerror(errno));
		free(request_id);
		return (PAPI_DEVICE_ERROR);
	}
#endif

	/* store the REQUEST on disk */
	snprintf(metadata_file, sizeof (metadata_file), "%s-0", request_id);
	free(request_id);
	if (putrequest(metadata_file, request) < 0) {
		detailed_error(svc, gettext("unable to save request: %s: %s"),
		    metadata_file, strerror(errno));
		return (PAPI_DEVICE_ERROR);
	}

	status = lpsched_commit_job(svc, metadata_file, &tmp);
	if (status != PAPI_OK) {
		unlink(metadata_file);
		return (status);
	}

	lpsched_request_to_job_attributes(request, j);

	if ((c = strrchr(tmp, '-')) != NULL)
		c++;
	papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
	    "job-id", atoi(c));
	papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE,
	    "job-uri", tmp);

	return (PAPI_OK);
}
Пример #8
0
papi_status_t
papiJobModify(papi_service_t handle, char *printer, int32_t job_id,
		papi_attribute_t **attributes, papi_job_t *job)
{
	papi_status_t status;
	job_t *j = NULL;
	service_t *svc = handle;
	char *file = NULL;
	char *dest;
	REQUEST *r = NULL;
	char lpfile[BUFSIZ];

	if ((svc == NULL) || (printer == NULL) || (job_id < 0) ||
	    (attributes == NULL))
		return (PAPI_BAD_ARGUMENT);

	if ((*job = j = calloc(1, sizeof (*j))) == NULL)
		return (PAPI_TEMPORARY_ERROR);

	dest = printer_name_from_uri_id(printer, job_id);
	status = lpsched_start_change(svc, dest, job_id, &file);
	if (status != PAPI_OK)
		return (status);

	if ((r = getrequest(file)) != NULL) {
		job_attributes_to_lpsched_request(handle, r,
		    (papi_attribute_t **)attributes);
#ifdef LP_USE_PAPI_ATTR
		/*
		 * store the job attributes in the PAPI job attribute file
		 * that was created by the origonal job request. We need to
		 * modify the attributes in the file as per the new attributes
		 */
		snprintf(lpfile, sizeof (lpfile), "%s%d-%s",
		    "/var/spool/lp/temp/", job_id, LP_PAPIATTRNAME);
		status = psm_modifyAttrsFile(attributes, lpfile);
		if (status != PAPI_OK) {
			detailed_error(svc,
			    "unable to modify the attributes file: %s: %s",
			    lpfile, strerror(errno));
			return (PAPI_DEVICE_ERROR);
		}
#endif

		if (putrequest(file, r) < 0) {
			detailed_error(svc,
			    gettext("failed to write job: %s: %s"),
			    file, strerror(errno));
			freerequest(r);
			return (PAPI_DEVICE_ERROR);
		}
	} else {
		detailed_error(svc, gettext("failed to read job: %s: %s"),
		    file, strerror(errno));
		return (PAPI_DEVICE_ERROR);
	}

	status = lpsched_end_change(svc, dest, job_id);
	lpsched_request_to_job_attributes(r, j);

	papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
	    "job-id", job_id);

	freerequest(r);

	return (status);
}
Пример #9
0
static int
mv_file(RSTATUS *rp, char *dest)
{
	int	stat;
	char	*olddest;
	EXEC	*oldexec;
	SECURE * securep;
	RSTATUS * prs;
	char *reqno;

	oldexec = rp->printer->exec;
	olddest = rp->request->destination;
	rp->request->destination = Strdup(dest);
	if ((stat = validate_request(rp, (char **)0, 1)) == MOK) {
		Free(olddest);

		if (rp->request->outcome & RS_FILTERED) {
			int cnt = 0;
			char *reqno;
			char **listp;
			char tmp_nam[MAXPATHLEN];

			reqno = getreqno(rp->secure->req_id);
			for (listp = rp->request->file_list; *listp; listp++) {
				cnt++;
				snprintf(tmp_nam, sizeof (tmp_nam),
				    "%s/F%s-%d", Lp_Temp, reqno, cnt);
				unlink(tmp_nam);

			}
			rp->request->outcome &= ~RS_FILTERED;
		}

		/* update /var/spool/lp/tmp/<host>/nnn-0 */
		if (putrequest(rp->req_file, rp->request) < 0) {
			note("putrequest failed\n");
			return (MNOMEM);
		}

		/* update /var/spool/lp/requests/<host>/nnn-0 */
		if ((securep = Getsecure(rp->req_file))) {
			reqno = strdup(getreqno(securep->req_id));
			(void) free(securep->req_id);
			if ((securep->req_id = calloc(strlen(dest) + 1 +
			    strlen(reqno) +1, sizeof (char))) == NULL)
				return (MNOMEM);
			(void) sprintf(securep->req_id, "%s-%s", dest, reqno);
			/* remove the old request file; save new one */
			(void) rmsecure(rp->secure->req_id);
			if (Putsecure(rp->req_file, securep) < 0) {
				/* Putsecure includes note/errmessage */
				return (MNOMEM);
			}
		} else {
			note("Getsecure failed\n");
			return (MNOMEM);
		}

		/* update internal jobs list: Request_list */
		if (prs = request_by_id(rp->secure->req_id)) {
			free(prs->secure->req_id);
			prs->secure->req_id = strdup(securep->req_id);

			/*
			 * We calloc'd securep->reqid earlier, now we free it
			 * here because we no longer call 'freesecure' from
			 * Putsecure() if we use a static structure
			 */

			free(securep->req_id);
		} else {
			note("request_by_id failed\n");
			return (MUNKNOWN);
		}

		/*
		 * If the request was being filtered or was printing,
		 * it would have been stopped in "validate_request()",
		 * but only if it has to be refiltered. Thus, the
		 * filtering has been stopped if it has to be stopped,
		 * but the printing may still be going.
		 */
		if (rp->request->outcome & RS_PRINTING &&
		    !(rp->request->outcome & RS_STOPPED)) {
			rp->request->outcome |= RS_STOPPED;
			terminate(oldexec);
		}

		maybe_schedule(rp);
		return (MOK);
	}

	Free(rp->request->destination);
	rp->request->destination = olddest;
	return (stat);
}
Пример #10
0
void
s_print_request(char *m, MESG *md)
{
	extern char		*Local_System;
	char			*file;
	char			*idno;
	char			*path;
	char			*req_file;
	char			*req_id	= 0;
	RSTATUS			*rp;
	REQUEST			*r;
	SECURE			*s;
	struct passwd		*pw;
	short			err;
	short			status;
	off_t			size;
	uid_t			org_uid;
	gid_t			org_gid;
#ifdef LP_USE_PAPI_ATTR
	struct stat		tmpBuf;
	char 			tmpName[BUFSIZ];
#endif


	(void) getmessage(m, S_PRINT_REQUEST, &file);
	syslog(LOG_DEBUG, "s_print_request(%s)", (file ? file : "NULL"));

	/*
	 * "NewRequest" points to a request that's not yet in the
	 * request list but is to be considered with the rest of the
	 * requests (e.g. calculating # of requests awaiting a form).
	 */
	if ((rp = NewRequest = new_rstatus(NULL, NULL)) == NULL)
		status = MNOMEM;

	else
	{
		req_file = reqpath(file, &idno);
		path = makepath(Lp_Tmp, req_file, (char *)0);
		(void) chownmod(path, Lp_Uid, Lp_Gid, 0644);
		Free(path);

		if (!(r = Getrequest(req_file)))
			status = MNOOPEN;

		else
		{
			rp->req_file = Strdup(req_file);

			freerequest(rp->request);
			rp->request = r;

			rp->request->outcome = 0;
			rp->secure->uid = md->uid;
			rp->secure->gid = md->gid;
			if (md->slabel != NULL)
				rp->secure->slabel = Strdup(md->slabel);

			pw = getpwuid(md->uid);
			endpwent();
			if (pw && pw->pw_name && *pw->pw_name)
				rp->secure->user = Strdup(pw->pw_name);
			else {
				rp->secure->user = Strdup(BIGGEST_NUMBER_S);
				(void) sprintf(rp->secure->user, "%u",
				    md->uid);
			}

			if ((rp->request->actions & ACT_SPECIAL) == ACT_HOLD)
				rp->request->outcome |= RS_HELD;
			if ((rp->request->actions & ACT_SPECIAL) == ACT_RESUME)
				rp->request->outcome &= ~RS_HELD;
			if ((rp->request->actions & ACT_SPECIAL) ==
			    ACT_IMMEDIATE) {
				if (!md->admin) {
					status = MNOPERM;
					goto Return;
				}
				rp->request->outcome |= RS_IMMEDIATE;
			}

			size = chfiles(rp->request->file_list, Lp_Uid, Lp_Gid);

			if (size < 0) {
				/*
				 * at this point, chfiles() may have
				 * failed because the file may live on
				 * an NFS mounted filesystem, under
				 * a directory of mode 700. such a
				 * directory isn't accessible even by
				 * root, according to the NFS protocol
				 * (i.e. the Stat() in chfiles() failed).
				 * this most commonly happens via the
				 * automounter, and rlogin. thus we
				 * change our euid/egid to that of the
				 * user, and try again. if *this* fails,
				 * then the file must really be
				 * inaccessible.
				 */
				org_uid = geteuid();
				org_gid = getegid();

				if (setegid(md->gid) != 0) {
					status = MUNKNOWN;
					goto Return;
				}

				if (seteuid(md->uid) != 0) {
					setgid(org_gid);
					status = MUNKNOWN;
					goto Return;
				}

				size = chfiles(rp->request->file_list,
				    Lp_Uid, Lp_Gid);

				if (seteuid(org_uid) != 0) {
					/* should never happen */
					note("s_print_request(): ");
					note("seteuid back to uid=%d "
					    "failed!!\n", org_uid);
					size = -1;
				}

				if (setegid(org_gid) != 0) {
					/* should never happen */
					note("s_print_request(): ");
					note("setegid back to uid=%d "
					    "failed!!\n", org_uid);
					size = -1;
				}

				if (size < 0) {
					status = MUNKNOWN;
					goto Return;
				}
			}
			if (!(rp->request->outcome & RS_HELD) && size == 0) {
				status = MNOPERM;
				goto Return;
			}
			rp->secure->size = size;

			(void) time(&rp->secure->date);
			rp->secure->req_id = NULL;

			if (!rp->request->title) {
				if (strlen(*rp->request->file_list) <
				    (size_t)24)
					rp->request->title =
					    Strdup(*rp->request->file_list);
				else {
					char *r;
					if (r = strrchr(
					    *rp->request->file_list, '/'))
						r++;
					else
						r = *rp->request->file_list;

					rp->request->title = malloc(25);
					sprintf(rp->request->title,
					    "%-.24s", r);
				}
			}

			if ((err = validate_request(rp, &req_id, 0)) != MOK)
				status = err;
			else {
				/*
				 * "req_id" will be supplied if this is from a
				 * remote system.
				 */
				if (rp->secure->req_id == NULL) {
					req_id = makestr(req_id, "-",
					    idno, (char *)0);
					rp->secure->req_id = req_id;
				} else
					req_id = rp->secure->req_id;

#ifdef LP_USE_PAPI_ATTR
				/*
				 * Check if the PAPI job attribute file
				 * exists, if it does change the
				 * permissions and ownership of the file.
				 * This file is created when print jobs
				 * are submitted via the PAPI interface,
				 * the file pathname of this file is
				 * passed to the slow-filters and printer
				 * interface script as an environment
				 * variable when they are executed
				 */
				snprintf(tmpName, sizeof (tmpName),
				    "%s-%s", idno, LP_PAPIATTRNAME);
				path = makepath(Lp_Temp, tmpName, (char *)0);

				if (stat(path, &tmpBuf) == 0) {
					syslog(LOG_DEBUG,
					    "s_print_request: "\
					    "attribute file ='%s'", path);

					/*
					 * IPP job attribute file exists
					 * for this job so change
					 * permissions and ownership of
					 * the file
					 */
					(void) chownmod(path, Lp_Uid,
					    Lp_Gid, 0644);
					Free(path);
				}
				else
				{
					syslog(LOG_DEBUG,
					    "s_print_request: "\
					    "no attribute file");
				}
#endif

				/*
				 * fix for bugid 1103890.
				 * use Putsecure instead.
				 */
				if ((Putsecure(req_file, rp->secure) == -1) ||
				    (putrequest(req_file, rp->request) == -1))
					status = MNOMEM;
				else
				{
					status = MOK;

					insertr(rp);
					NewRequest = 0;

					if (rp->slow)
						schedule(EV_SLOWF, rp);
					else
						schedule(EV_INTERF,
						    rp->printer);

					del_flt_act(md, FLT_FILES);
				}
			}
		}
	}

Return:
	NewRequest = 0;
	Free(req_file);
	Free(idno);
	if (status != MOK && rp) {
		rmfiles(rp, 0);
		free_rstatus(rp);
	}
	mputm(md, R_PRINT_REQUEST, status, NB(req_id), chkprinter_result);
}
Пример #11
0
void
s_end_change_request(char *m, MESG *md)
{
	char		*req_id;
	RSTATUS		*rp;
	off_t		size;
	off_t		osize;
	short		err;
	short		status;
	REQUEST		*r = 0;
	REQUEST		oldr;
	int		call_schedule = 0;
	int		move_ok	= 0;
	char		*path;
	char		tmpName[BUFSIZ];
	struct stat	tmpBuf;

	(void) getmessage(m, S_END_CHANGE_REQUEST, &req_id);
	syslog(LOG_DEBUG, "s_end_change_request(%s)",
	    (req_id ? req_id : "NULL"));

	if (!(rp = request_by_id(req_id)))
		status = MUNKNOWN;
	else if ((md->admin == 0) && (is_system_labeled()) &&
	    (md->slabel != NULL) && (rp->secure->slabel != NULL) &&
	    (!STREQU(md->slabel, rp->secure->slabel)))
		status = MUNKNOWN;
	else if (!(rp->request->outcome & RS_CHANGING))
		status = MNOSTART;
	else {
		path = makepath(Lp_Tmp, rp->req_file, (char *)0);
		(void) chownmod(path, Lp_Uid, Lp_Gid, 0644);
		Free(path);

#ifdef LP_USE_PAPI_ATTR

		/*
		 * Check if the PAPI job attribute file exists,
		 * if it does change the permission and the ownership
		 * of the file to be "Lp_Uid".
		 */

		snprintf(tmpName, sizeof (tmpName),
		    "%s-%s", strtok(strdup(rp->req_file), "-"),
		    LP_PAPIATTRNAME);

		path = makepath(Lp_Tmp, tmpName, (char *)0);

		if (stat(path, &tmpBuf) == 0) {
			syslog(LOG_DEBUG,
			    "s_end_change_request: attribute file ='%s'",
			    path);

			/*
			 * IPP job attribute file exists for this job so
			 * change permissions and ownership of the file
			 */
			(void) chownmod(path, Lp_Uid, Lp_Gid, 0644);
			Free(path);
		}
		else
		{
			syslog(LOG_DEBUG,
			    "s_end_change_request: no attribute file");
		}
#endif
		rp->request->outcome &= ~(RS_CHANGING);
		del_flt_act(md, FLT_CHANGE);
		/*
		 * The RS_CHANGING bit may have been the only thing
		 * preventing this request from filtering or printing,
		 * so regardless of what happens below,
		 * we must check to see if the request can proceed.
		 */
		call_schedule = 1;

		if (!(r = Getrequest(rp->req_file)))
			status = MNOOPEN;
		else {
			oldr = *(rp->request);
			*(rp->request) = *r;

			move_ok =
			    STREQU(oldr.destination, r->destination);

			/*
			 * Preserve the current request status!
			 */
			rp->request->outcome = oldr.outcome;

			/*
			 * Here's an example of the dangers one meets
			 * when public flags are used for private
			 * purposes. ".actions" (indeed, anything in the
			 * REQUEST structure) is set by the person
			 * changing the job. However, lpsched uses
			 * ".actions" as place to indicate that a job
			 * came from a remote system and we must send
			 * back job completion--this is a strictly
			 * private flag that we must preserve.
			 */
			rp->request->actions |=
			    (oldr.actions & ACT_NOTIFY);

			if ((rp->request->actions & ACT_SPECIAL) ==
			    ACT_HOLD) {
				rp->request->outcome |= RS_HELD;
				/*
				 * To be here means either the user owns
				 * the request or he or she is the
				 * administrator. Since we don't want to
				 * set the RS_ADMINHELD flag if the user
				 * is the administrator, the following
				 * compare will work.
				 */
				if (md->uid != rp->secure->uid)
					rp->request->outcome |=
					    RS_ADMINHELD;
			}

			if ((rp->request->actions & ACT_SPECIAL) ==
			    ACT_RESUME) {
				if ((rp->request->outcome & RS_ADMINHELD) &&
				    !md->admin) {
					status = MNOPERM;
					goto Return;
				}
				rp->request->outcome &=
				    ~(RS_ADMINHELD|RS_HELD);
			}

			if ((rp->request->actions & ACT_SPECIAL)
			    == ACT_IMMEDIATE) {
				if (!md->admin) {
					status = MNOPERM;
					goto Return;
				}
				rp->request->outcome |= RS_IMMEDIATE;
			}

			size = chfiles(rp->request->file_list, Lp_Uid,
			    Lp_Gid);
			if (size < 0) {
				status = MUNKNOWN;
				goto Return;
			}
			if (!(rp->request->outcome & RS_HELD) &&
			    size == 0) {
				status = MNOPERM;
				goto Return;
			}

			osize = rp->secure->size;
			rp->secure->size = size;

			if (move_ok == 0) {
				char *dest = strdup(r->destination);
				if ((status = mv_file(rp, dest)) == MOK)
					rp->secure->size = osize;
				free(dest);
			} else if ((err = validate_request(rp, (char **)0,
			    move_ok)) != MOK) {
				status = err;
				rp->secure->size = osize;
			} else {
				status = MOK;

				if ((rp->request->outcome & RS_IMMEDIATE) ||
				    (rp->request->priority != oldr.priority)) {
					remover(rp);
					insertr(rp);
				}

				freerequest(&oldr);
				(void) putrequest(rp->req_file, rp->request);
				/*
				 * fix for bugid 1103890.
				 * use Putsecure instead.
				 */
				(void) Putsecure(rp->req_file, rp->secure);
			}
		}
	}

Return:
	if (status != MOK && rp) {
		if (r) {
			freerequest(r);
			*(rp->request) = oldr;
		}
		if (status != MNOSTART)
			(void) putrequest(rp->req_file, rp->request);
	}

	if (call_schedule)
		maybe_schedule(rp);

	mputm(md, R_END_CHANGE_REQUEST, status, chkprinter_result);
}
Пример #12
0
papi_status_t
papiJobSubmit(papi_service_t handle, char *printer,
		papi_attribute_t **job_attributes,
		papi_job_ticket_t *job_ticket,
		char **files, papi_job_t *job)
{
	papi_status_t status;
	service_t *svc = handle;
	job_t *j;
	int file_no;
	char *request_id = NULL;
	REQUEST *request;
	int i;
	char *c;
	char *tmp = NULL;
	char lpfile[BUFSIZ];

	if ((svc == NULL) || (printer == NULL) || (files == NULL) ||
	    (job == NULL))
		return (PAPI_BAD_ARGUMENT);

	if (job_ticket != NULL)
		return (PAPI_OPERATION_NOT_SUPPORTED);

	if (files != NULL)
		for (file_no = 0; files[file_no] != NULL; file_no++)
			if (access(files[file_no], R_OK) < 0) {
				detailed_error(svc,
					gettext("Cannot access file: %s: %s"),
					files[file_no], strerror(errno));
				return (PAPI_BAD_ARGUMENT);
			}

	if ((*job = j = calloc(1, sizeof (*j))) == NULL)
		return (PAPI_TEMPORARY_ERROR);

	/* file_no + 1 for the control file (-0) */
	status = lpsched_alloc_files(svc, file_no + 1, &request_id);
	if (status != PAPI_OK)
		return (status);

	request = create_request(svc, (char *)printer,
				(papi_attribute_t **)job_attributes);

	for (i = 0; files[i] != NULL; i++) {
		papi_status_t status;
		snprintf(lpfile, sizeof (lpfile), "%s%s-%d",
			"/var/spool/lp/temp/", request_id, i+1);
		status = copy_file(files[i], lpfile);
		if (status != PAPI_OK) {
			detailed_error(svc,
				gettext("unable to copy: %s -> %s: %s"),
				files[i], lpfile, strerror(errno));
				freerequest(request);
			return (PAPI_DEVICE_ERROR);
		}
		addlist(&(request->file_list), lpfile);
	}

#ifdef LP_USE_PAPI_ATTR
	/*
	 * store the job attributes in the PAPI job attribute file that was
	 * created by lpsched_alloc_files(), the attributes will then pass
	 * through lpsched and be given to the slow-filters and the printer's
	 * interface script to process them
	 */
	snprintf(lpfile, sizeof (lpfile), "%s%s-%s",
		"/var/spool/lp/temp/", request_id, LP_PAPIATTRNAME);
	status = psm_copy_attrsToFile(job_attributes, lpfile);
	if (status != PAPI_OK) {
		detailed_error(svc, "unable to copy attributes to file: %s: %s",
				lpfile, strerror(errno));
		return (PAPI_DEVICE_ERROR);
	}
#endif

	/* store the meta-data file */
	snprintf(lpfile, sizeof (lpfile), "%s-0", request_id);
	if (putrequest(lpfile, request) < 0) {
		detailed_error(svc, gettext("unable to save request: %s: %s"),
			lpfile, strerror(errno));
		freerequest(request);
		return (PAPI_DEVICE_ERROR);
	}

	status = lpsched_commit_job(svc, lpfile, &tmp);
	if (status != PAPI_OK) {
		unlink(lpfile);
		freerequest(request);
		return (status);
	}

	lpsched_request_to_job_attributes(request, j);
	freerequest(request);

	if ((c = strrchr(tmp, '-')) != NULL)
		c++;
	papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
			"job-id", atoi(c));
	papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE,
			"job-uri", tmp);

	return (PAPI_OK);
}
Пример #13
0
Файл: miscd.c Проект: wyat/kbs
void utmpd()
{
    int m_socket;

    struct sockaddr_in sin;
    int sinlen = sizeof(sin);
    int opt = 1;

    bzero(&sin, sizeof(sin));
    if ((m_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
        bbslog("3system", "utmpd:socket %s", strerror(errno));
        exit(-1);
    }
    setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, &opt, 4);
    memset(&sin, 0, sinlen);
    sin.sin_family = AF_INET;
#ifdef CELESTIS
    sin.sin_port = htons(61002);
#else
    sin.sin_port = htons(60002);
#endif
#ifdef HAVE_INET_ATON
    inet_aton("127.0.0.1", &sin.sin_addr);
#elif defined HAVE_INET_PTON
    inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr);
#else
    /* Is it OK? */
    my_inet_aton("127.0.0.1", &sin.sin_addr);
#endif
    if (0 != bind(m_socket, (struct sockaddr *) &sin, sizeof(sin))) {
        bbslog("3system", "utmpd:bind %s", strerror(errno));
        exit(-1);
    }
    if (0 != listen(m_socket, 5)) {
        bbslog("3system", "utmpd:listen %s", strerror(errno));
        exit(-1);
    }
    while (1) {
        int sock, id;

        sock = getutmprequest(m_socket);
#if 0
        {                       /*kill user */
            time_t now;
            struct user_info *uentp;

            now = time(NULL);
            if ((now > utmpshm->uptime + 120) || (now < utmpshm->uptime - 120)) {
                int n;

                utmpshm->uptime = now;
                bbslog("1system", "UTMP:Clean user utmp cache");
                for (n = 0; n < USHM_SIZE; n++) {
                    utmpshm->uptime = now;
                    uentp = &(utmpshm->uinfo[n]);
                    if (uentp->active && uentp->pid && kill(uentp->pid, 0) == -1) {     /*uentp检查 */
                        char buf[STRLEN];

                        strncpy(buf, uentp->userid, IDLEN + 2);
                        clear_utmp(n + 1);
                        RemoveMsgCountFile(buf);
                    }
                }
            }
        }
#endif
        /* utmp */
        switch (utmpreq.command) {
        case 1:                // getnewutmp
            id = getnewutmpent2(&utmpreq.u_info.utmp, 0 /* TODO ! */);
            break;
        case 2:
            id = -1;
            break;              // clear, by uentp
        case 3:                // clear, by id
            /*这个代码有错误的,因为pid不能不判断 */
            clear_utmp(utmpreq.u_info.uent, 0, 0);
            id = 0;
            break;
        default:
            id = -1;
            break;
        }
        putrequest(sock, id);
    }
    return;
}
Пример #14
0
Файл: miscd.c Проект: wyat/kbs
void userd()
{
    int m_socket;

#ifdef HAVE_IPV6_SMTH
    struct sockaddr_in6 sin;
#else
    struct sockaddr_in sin;
#endif
    int sinlen = sizeof(sin);
    int opt = 1;

    bzero(&sin, sizeof(sin));
#ifdef HAVE_IPV6_SMTH
    if ((m_socket = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0)
#else
    if ((m_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
#endif
    {
        bbslog("3system", "userd:socket %s", strerror(errno));
        exit(-1);
    }
    setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, &opt, 4);
    memset(&sin, 0, sinlen);
#ifdef HAVE_IPV6_SMTH
    sin.sin6_family = AF_INET6;
    sin.sin6_port = htons(USERD_PORT);
    inet_pton(AF_INET6, "::1", &sin.sin6_addr);
#else 
    sin.sin_family = AF_INET;
    sin.sin_port = htons(USERD_PORT);
#ifdef HAVE_INET_ATON
    inet_aton("127.0.0.1", &sin.sin_addr);
#elif defined HAVE_INET_PTON
    inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr);
#else
    /* Is it OK? */
    my_inet_aton("127.0.0.1", &sin.sin_addr);
#endif
#endif /* IPV6 */
    if (0 != bind(m_socket, (struct sockaddr *) &sin, sizeof(sin))) {
        bbslog("3system", "userd:bind %s", strerror(errno));
        exit(-1);
    }
    if (0 != listen(m_socket, 5)) {
        bbslog("3system", "userd:listen %s", strerror(errno));
        exit(-1);
    }
    while (1) {
        int sock, id;

        sock = getrequest(m_socket);
#ifndef SECONDSITE
        if (!strcmp(cmd, "NEW"))
            id = getnewuserid(username);
        else
#endif
        if (!strcmp(cmd, "SET")) {
            setuserid2(num, username);
            id = 0;
        }
        else if (!strcmp(cmd, "DEL")) {
            setuserid2(num, "");
            id = 0;
        } else
            continue;
        putrequest(sock, id);
    }
    return;
}