Print this page
Bump Apache dependency to Apache 2
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/print/libipp-listener/common/ipp-listener.c
+++ new/usr/src/lib/print/libipp-listener/common/ipp-listener.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 + * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
23 24 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 25 * Use is subject to license terms.
25 26 *
26 27 */
27 28
28 29 /* $Id: ipp-listener.c 146 2006-03-24 00:26:54Z njacobs $ */
29 30
30 -#pragma ident "%Z%%M% %I% %E% SMI"
31 -
32 31 #include <stdio.h>
33 32 #include <stdlib.h>
34 33 #include <string.h>
35 34 #include <netinet/in.h>
36 35 #include <assert.h>
37 36 #include <errno.h>
38 37 #include <syslog.h>
39 38 #include <sys/types.h>
40 39 #include <sys/stat.h>
41 40 #include <fcntl.h>
42 41 #include <unistd.h>
43 42 #include <sys/systeminfo.h>
44 43
45 44 #include <papi.h>
46 45 #include <ipp-listener.h>
47 46 #include <uri.h>
48 47
49 48 typedef papi_status_t (ipp_handler_t)(papi_service_t svc,
50 49 papi_attribute_t **request,
51 50 papi_attribute_t ***response,
52 51 ipp_reader_t iread, void *fd);
53 52
54 53 /*
55 54 * protocol request handlers are inserted below. The handler must be
56 55 * declared extern immediately below this comment and then an entry
57 56 * must be inserted in the "handlers" table a little further down.
58 57 */
59 58 extern ipp_handler_t ipp_print_job;
60 59 extern ipp_handler_t ipp_validate_job;
61 60 extern ipp_handler_t ipp_create_job;
62 61 extern ipp_handler_t ipp_get_printer_attributes;
63 62 extern ipp_handler_t ipp_get_jobs;
64 63 extern ipp_handler_t ipp_pause_printer;
65 64 extern ipp_handler_t ipp_resume_printer;
66 65 extern ipp_handler_t ipp_disable_printer;
67 66 extern ipp_handler_t ipp_enable_printer;
68 67 extern ipp_handler_t ipp_purge_jobs;
69 68 extern ipp_handler_t ipp_send_document;
70 69 extern ipp_handler_t ipp_cancel_job;
71 70 extern ipp_handler_t ipp_get_job_attributes;
72 71 extern ipp_handler_t ipp_release_job;
73 72 extern ipp_handler_t ipp_hold_job;
74 73 extern ipp_handler_t ipp_restart_job;
75 74 extern ipp_handler_t ipp_set_job_attributes;
76 75 extern ipp_handler_t ipp_set_printer_attributes;
77 76 extern ipp_handler_t cups_get_default;
78 77 extern ipp_handler_t cups_get_printers;
79 78 extern ipp_handler_t cups_get_classes;
80 79 extern ipp_handler_t cups_accept_jobs;
81 80 extern ipp_handler_t cups_reject_jobs;
82 81 extern ipp_handler_t cups_move_job;
83 82
84 83 /* ARGSUSED0 */
85 84 static papi_status_t
86 85 default_handler(papi_service_t svc, papi_attribute_t **request,
87 86 papi_attribute_t ***response, ipp_reader_t iread, void *fd)
88 87 {
89 88 int result = (int)PAPI_INTERNAL_ERROR;
90 89
91 90 if (response != NULL)
92 91 (void) papiAttributeListGetInteger(*response, NULL,
93 92 "status-code", &result);
94 93
95 94 return ((papi_status_t)result);
96 95 }
97 96
98 97 static struct {
99 98 int16_t id;
100 99 char *name;
101 100 ipp_handler_t *function;
102 101 enum { OP_REQUIRED, OP_OPTIONAL, OP_VENDOR } type;
103 102 } handlers[] = {
104 103 /* Printer Operations */
105 104 { 0x0002, "print-job", ipp_print_job, OP_REQUIRED },
106 105 { 0x0003, "print-uri", NULL, OP_OPTIONAL },
107 106 { 0x0004, "validate-job", ipp_validate_job,
108 107 OP_REQUIRED },
109 108 { 0x0005, "create-job", ipp_create_job, OP_OPTIONAL },
110 109 { 0x000a, "get-jobs", ipp_get_jobs, OP_REQUIRED },
111 110 { 0x000b, "get-printer-attributes", ipp_get_printer_attributes,
112 111 OP_REQUIRED },
113 112 { 0x0010, "pause-printer", ipp_pause_printer,
114 113 OP_OPTIONAL },
115 114 { 0x0011, "resume-printer", ipp_resume_printer,
116 115 OP_OPTIONAL },
117 116 { 0x0012, "purge-jobs", ipp_purge_jobs, OP_OPTIONAL },
118 117 { 0x0013, "set-printer-attributes", ipp_set_printer_attributes,
119 118 OP_OPTIONAL },
120 119 { 0x0014, "set-job-attributes", ipp_set_job_attributes,
121 120 OP_OPTIONAL },
122 121 { 0x0022, "enable-printer", ipp_enable_printer,
123 122 OP_OPTIONAL },
124 123 { 0x0023, "disable-printer", ipp_disable_printer,
125 124 OP_OPTIONAL },
126 125 /* Job Operations */
127 126 { 0x0006, "send-document", ipp_send_document,
128 127 OP_OPTIONAL },
129 128 { 0x0007, "send-uri", NULL, OP_OPTIONAL },
130 129 { 0x0008, "cancel-job", ipp_cancel_job, OP_REQUIRED },
131 130 { 0x0009, "get-job-attributes", ipp_get_job_attributes,
132 131 OP_REQUIRED },
133 132 { 0x000c, "hold-job", ipp_hold_job, OP_OPTIONAL },
134 133 { 0x000d, "release-job", ipp_release_job,
135 134 OP_OPTIONAL },
136 135 { 0x000e, "restart-job", ipp_restart_job,
137 136 OP_OPTIONAL },
138 137 /* Other Operations */
139 138 { 0x4001, "cups-get-default", cups_get_default,
140 139 OP_VENDOR },
141 140 { 0x4002, "cups-get-printers", cups_get_printers,
142 141 OP_VENDOR },
143 142 { 0x4005, "cups-get-classes", cups_get_classes,
↓ open down ↓ |
102 lines elided |
↑ open up ↑ |
144 143 OP_VENDOR },
145 144 { 0x4008, "cups-accept-jobs", cups_accept_jobs,
146 145 OP_VENDOR },
147 146 { 0x4009, "cups-reject-jobs", cups_reject_jobs,
148 147 OP_VENDOR },
149 148 { 0x400D, "cups-move-job", cups_move_job, OP_VENDOR },
150 149 { 0, NULL, NULL, OP_VENDOR }
151 150 };
152 151
153 152 static int
154 -ipp_operation_name_to_index(char *name)
153 +ipp_operation_name_to_index(const char *name)
155 154 {
156 155 int i;
157 156
158 157 for (i = 0; handlers[i].name != NULL; i++)
159 158 if (strcasecmp(name, handlers[i].name) == 0)
160 159 return (i);
161 160
162 161 return (-1);
163 162 }
164 163
165 164 static int
166 165 ipp_operation_id_to_index(int16_t id)
167 166 {
168 167 int i;
169 168
170 169 for (i = 0; handlers[i].name != NULL; i++)
171 170 if (id == handlers[i].id)
172 171 return (i);
173 172
174 173 return (-1);
175 174 }
176 175
177 176 static ipp_handler_t *
178 177 ipp_operation_handler(papi_attribute_t **request, papi_attribute_t ***response)
179 178 {
180 179 int id = 0;
181 180 int index;
182 181 papi_attribute_t **ops = NULL;
183 182 papi_status_t status;
184 183 char configured = PAPI_FALSE;
185 184
186 185 /* get the operation from the request */
187 186 status = papiAttributeListGetInteger(request, NULL,
188 187 "operation-id", &id);
189 188 if (status != PAPI_OK) {
190 189 ipp_set_status(response, PAPI_BAD_ARGUMENT,
191 190 "no operation specified in request");
192 191 return (default_handler);
193 192 }
194 193
195 194 /* find the operation in the handler table */
196 195 index = ipp_operation_id_to_index(id);
197 196 #ifdef DEBUG
198 197 if (index == -1)
199 198 fprintf(stderr, "Operation: 0x%4.4x\n", id);
200 199 else
201 200 fprintf(stderr, "Operation: 0x%4.4x(%s)\n", id,
202 201 handlers[index].name);
203 202 fflush(stderr);
204 203 #endif
205 204
206 205 if ((index == -1) || (handlers[index].function == NULL)) {
207 206 ipp_set_status(response, PAPI_OPERATION_NOT_SUPPORTED,
208 207 "operation (0x%4.4x) not implemented by server",
209 208 id);
210 209 return (default_handler);
211 210 }
212 211
213 212 /* find the configured operations */
214 213 status = papiAttributeListGetCollection(request, NULL,
215 214 "operations", &ops);
216 215 if (status != PAPI_OK) { /* this should not be possible */
217 216 ipp_set_status(response, PAPI_INTERNAL_ERROR,
218 217 "sofware error, no operations configured");
219 218 return (default_handler);
220 219 }
221 220
222 221 /* check if the requested operation is configured */
223 222 status = papiAttributeListGetBoolean(ops, NULL,
224 223 handlers[index].name, &configured);
225 224 if ((status != PAPI_OK) || (configured != PAPI_TRUE)) {
↓ open down ↓ |
61 lines elided |
↑ open up ↑ |
226 225 ipp_set_status(response, PAPI_OPERATION_NOT_SUPPORTED,
227 226 "operation (%s 0x%4.4x) not enabled on server",
228 227 handlers[index].name, id);
229 228 return (default_handler);
230 229 }
231 230
232 231 return (handlers[index].function);
233 232 }
234 233
235 234 static char
236 -type_to_boolean(char *type)
235 +type_to_boolean(const char *type)
237 236 {
238 237 char result = PAPI_FALSE;
239 238
240 239 if ((strcasecmp(type, "true") == 0) ||
241 240 (strcasecmp(type, "yes") == 0) ||
242 241 (strcasecmp(type, "on") == 0) ||
243 242 (strcasecmp(type, "enable") == 0))
244 243 result = PAPI_TRUE;
245 244
246 245 return (result);
247 246 }
248 247
249 248 static papi_status_t
250 249 ipp_configure_required_operations(papi_attribute_t ***list, char boolean)
251 250 {
252 251 papi_status_t result = PAPI_OK;
253 252 int i;
254 253
255 254 for (i = 0; ((result == PAPI_OK) && (handlers[i].name != NULL)); i++)
256 255 if (handlers[i].type == OP_REQUIRED)
257 256 result = papiAttributeListAddBoolean(list,
258 257 PAPI_ATTR_REPLACE, handlers[i].name,
259 258 boolean);
260 259
261 260 return (result);
262 261
263 262 }
264 263
265 264 static papi_status_t
266 265 ipp_configure_all_operations(papi_attribute_t ***list, char boolean)
267 266 {
268 267 papi_status_t result = PAPI_OK;
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
269 268 int i;
270 269
271 270 for (i = 0; ((result == PAPI_OK) && (handlers[i].name != NULL)); i++)
272 271 result = papiAttributeListAddBoolean(list, PAPI_ATTR_REPLACE,
273 272 handlers[i].name, boolean);
274 273
275 274 return (result);
276 275 }
277 276
278 277 papi_status_t
279 -ipp_configure_operation(papi_attribute_t ***list, char *operation, char *type)
278 +ipp_configure_operation(papi_attribute_t ***list, const char *operation, const char *type)
280 279 {
281 280 papi_status_t result = PAPI_OPERATION_NOT_SUPPORTED;
282 281 char boolean = PAPI_FALSE;
283 282
284 283 if ((list == NULL) || (operation == NULL) || (type == NULL))
285 284 return (PAPI_BAD_ARGUMENT);
286 285
287 286 boolean = type_to_boolean(type);
288 287
289 288 if (strcasecmp(operation, "all") == 0) {
290 289 result = ipp_configure_all_operations(list, boolean);
291 290 } else if (strcasecmp(operation, "required") == 0) {
292 291 result = ipp_configure_required_operations(list, boolean);
293 292 } else if (ipp_operation_name_to_index(operation) != -1) {
294 293 result = papiAttributeListAddBoolean(list, PAPI_ATTR_REPLACE,
295 294 operation, boolean);
296 295 }
297 296
298 297 return (result);
299 298 }
300 299
301 300 void
302 301 ipp_operations_supported(papi_attribute_t ***list, papi_attribute_t **request)
303 302 {
304 303 papi_attribute_t **group = NULL;
305 304
306 305 (void) papiAttributeListGetCollection(request, NULL,
307 306 "operations", &group);
308 307 if (group != NULL) {
309 308 int i;
310 309
311 310 for (i = 0; handlers[i].name != NULL; i++) {
312 311 char boolean = PAPI_FALSE;
313 312 (void) papiAttributeListGetBoolean(group, NULL,
314 313 handlers[i].name, &boolean);
315 314
316 315 if (boolean == PAPI_TRUE)
317 316 (void) papiAttributeListAddInteger(list,
318 317 PAPI_ATTR_APPEND,
319 318 "operations-supported",
320 319 handlers[i].id);
321 320 }
322 321 }
323 322 }
324 323
325 324 static papi_status_t
326 325 ipp_initialize_response(papi_attribute_t **request,
327 326 papi_attribute_t ***response)
328 327 {
329 328 papi_attribute_t **operational = NULL;
330 329 int i;
331 330
332 331 if ((request == NULL) || (response == NULL))
333 332 return (PAPI_BAD_ARGUMENT);
334 333
335 334 /* If the response was initialized, start over */
336 335 if (*response != NULL) {
337 336 papiAttributeListFree(*response);
338 337 *response = NULL;
339 338 }
340 339
341 340 /* Add the basic ipp header information to the response */
342 341 (void) papiAttributeListGetInteger(request, NULL, "version-major", &i);
343 342 (void) papiAttributeListAddInteger(response, PAPI_ATTR_REPLACE,
344 343 "version-major", i);
345 344 (void) papiAttributeListGetInteger(request, NULL, "version-minor", &i);
346 345 (void) papiAttributeListAddInteger(response, PAPI_ATTR_REPLACE,
347 346 "version-minor", i);
348 347
349 348 (void) papiAttributeListGetInteger(request, NULL, "request-id", &i);
350 349 (void) papiAttributeListAddInteger(response, PAPI_ATTR_REPLACE,
351 350 "request-id", i);
352 351
353 352 /* Add a default operational attributes group to the response */
354 353 (void) papiAttributeListAddString(&operational, PAPI_ATTR_EXCL,
355 354 "attributes-charset", "utf-8");
356 355 (void) papiAttributeListAddString(&operational, PAPI_ATTR_EXCL,
357 356 "attributes-natural-language", "en-us");
358 357
359 358 (void) papiAttributeListAddCollection(response, PAPI_ATTR_REPLACE,
360 359 "operational-attributes-group", operational);
361 360 papiAttributeListFree(operational);
362 361
363 362 return (PAPI_OK);
364 363 }
365 364
366 365 /* simplistic check for cyclical service references */
367 366 static int
368 367 cyclical_service_check(char *svc_name, int port)
369 368 {
370 369 papi_attribute_t **list;
371 370 char buf[BUFSIZ];
372 371 uri_t *uri = NULL;
373 372 char *s = NULL;
374 373
375 374 /* was there a service_uri? */
376 375 if (svc_name == NULL)
377 376 return (0);
378 377
379 378 if ((list = getprinterbyname(svc_name, NULL)) == NULL)
380 379 return (0); /* if it doesnt' resolve, we will fail later */
381 380
382 381 papiAttributeListGetString(list, NULL, "printer-uri-supported", &s);
383 382 if ((s == NULL) || (strcasecmp(svc_name, s) != 0))
384 383 return (0); /* they don't match */
385 384
386 385 /* is it in uri form? */
387 386 if (uri_from_string(s, &uri) < 0)
388 387 return (0);
389 388
390 389 if ((uri == NULL) || (uri->scheme == NULL) || (uri->host == NULL)) {
391 390 uri_free(uri);
392 391 return (0);
393 392 }
394 393
395 394 /* is it ipp form */
396 395 if (strcasecmp(uri->scheme, "ipp") != 0) {
397 396 uri_free(uri);
398 397 return (0);
399 398 }
400 399
401 400 /* does the host match up */
402 401 if (is_localhost(uri->host) != 0) {
403 402 uri_free(uri);
404 403 return (0);
405 404 }
406 405
407 406 /* does the port match our own */
408 407 if (((uri->port == NULL) && (port != 631)) ||
409 408 ((uri->port != NULL) && (atoi(uri->port) != port))) {
410 409 uri_free(uri);
411 410 return (0);
412 411 }
413 412
414 413 uri_free(uri);
415 414
416 415 return (1);
417 416 }
418 417
419 418 static papi_status_t
420 419 print_service_connect(papi_service_t *svc, papi_attribute_t **request,
421 420 papi_attribute_t ***response)
422 421 {
423 422 papi_status_t status;
424 423 papi_attribute_t **operational = NULL;
425 424 char *printer_uri = NULL;
426 425 char *svc_name = NULL;
427 426 char *user = NULL;
428 427 int port = 631;
429 428
430 429 /* Get the operational attributes group from the request */
431 430 (void) papiAttributeListGetCollection(request, NULL,
432 431 "operational-attributes-group", &operational);
433 432
434 433 /* get the user name */
435 434 (void) papiAttributeListGetString(request, NULL, "default-user", &user);
436 435 (void) papiAttributeListGetString(operational, NULL,
437 436 "requesting-user-name", &user);
438 437
439 438 /* get the printer or service name */
440 439 (void) papiAttributeListGetString(request, NULL,
441 440 "default-service", &svc_name);
442 441 get_printer_id(operational, &svc_name, NULL);
443 442
444 443 /* get the port that we are listening on */
445 444 (void) papiAttributeListGetInteger(request, NULL, "uri-port", &port);
446 445
447 446 if (cyclical_service_check(svc_name, port) != 0) {
448 447 status = PAPI_NOT_POSSIBLE;
449 448 ipp_set_status(response, status, "printer-uri is cyclical");
450 449 return (status);
451 450 }
452 451
453 452 status = papiServiceCreate(svc, svc_name, user, NULL, NULL,
454 453 PAPI_ENCRYPT_NEVER, NULL);
455 454 if (status != PAPI_OK) {
456 455 ipp_set_status(response, status, "print service: %s",
457 456 papiStatusString(status));
458 457 return (status);
459 458 }
460 459
461 460 /*
462 461 * Trusted Solaris can't be trusting of intermediaries. Pass
463 462 * the socket connection to the print service to retrieve the
464 463 * sensativity label off of a multi-level port.
465 464 */
466 465 {
467 466 int fd = -1;
468 467
469 468 (void) papiAttributeListGetInteger(request, NULL,
470 469 "peer-socket", &fd);
471 470 if (fd != -1)
472 471 papiServiceSetPeer(*svc, fd);
473 472 }
474 473
475 474 return (status);
476 475 }
477 476
478 477 papi_status_t
479 478 ipp_process_request(papi_attribute_t **request, papi_attribute_t ***response,
480 479 ipp_reader_t iread, void *fd)
481 480 {
482 481 papi_status_t result = PAPI_OK;
483 482
484 483 ipp_initialize_response(request, response);
485 484
486 485 #ifdef DEBUG
487 486 fprintf(stderr, "REQUEST:");
488 487 papiAttributeListPrint(stderr, request, " %d ", getpid());
489 488 fprintf(stderr, "\n");
490 489 #endif
491 490
492 491 /* verify that the request is "well-formed" */
493 492 if ((result = ipp_validate_request(request, response)) == PAPI_OK) {
494 493 papi_service_t svc = NULL;
495 494 ipp_handler_t *handler;
496 495
497 496 result = print_service_connect(&svc, request, response);
498 497 handler = ipp_operation_handler(request, response);
499 498
500 499 /* process the request */
501 500 if ((result == PAPI_OK) && (handler != NULL))
502 501 result = (handler)(svc, request, response, iread, fd);
503 502 #ifdef DEBUG
504 503 fprintf(stderr, "RESULT: %s\n", papiStatusString(result));
505 504 #endif
506 505 papiServiceDestroy(svc);
507 506 }
508 507
509 508 (void) papiAttributeListAddInteger(response, PAPI_ATTR_EXCL,
510 509 "status-code", result);
511 510 massage_response(request, *response);
512 511
513 512 #ifdef DEBUG
514 513 fprintf(stderr, "RESPONSE:");
515 514 papiAttributeListPrint(stderr, *response, " %d ", getpid());
516 515 fprintf(stderr, "\n");
517 516 #endif
518 517
519 518 return (result);
520 519 }
↓ open down ↓ |
231 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX