]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/auth.c
Merge changes from CUPS 1.4svn-r8540.
[thirdparty/cups.git] / cups / auth.c
CommitLineData
ef416fc2 1/*
b19ccc9e 2 * "$Id: auth.c 7720 2008-07-11 22:46:21Z mike $"
ef416fc2 3 *
4 * Authentication functions for the Common UNIX Printing System (CUPS).
5 *
e07d4801 6 * Copyright 2007-2009 by Apple Inc.
b86bc4cf 7 * Copyright 1997-2007 by Easy Software Products.
ef416fc2 8 *
f7deaa1a 9 * This file contains Kerberos support code, copyright 2006 by
10 * Jelmer Vernooij.
11 *
ef416fc2 12 * These coded instructions, statements, and computer programs are the
bc44d920 13 * property of Apple Inc. and are protected by Federal copyright
14 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
15 * which should have been included with this file. If this file is
16 * file is missing or damaged, see the license at "http://www.cups.org/".
ef416fc2 17 *
18 * This file is subject to the Apple OS-Developed Software exception.
19 *
20 * Contents:
21 *
22 * cupsDoAuthentication() - Authenticate a request.
e07d4801
MS
23 * cups_get_gssname() - Get GSSAPI name for authentication.
24 * cups_gss_printf() - Show error messages from GSSAPI...
ef416fc2 25 * cups_local_auth() - Get the local authorization certificate if
26 * available/applicable...
27 */
28
29/*
30 * Include necessary headers...
31 */
32
33#include "globals.h"
34#include "debug.h"
35#include <stdlib.h>
36#include <ctype.h>
37#include <errno.h>
38#include <fcntl.h>
39#include <sys/stat.h>
40#if defined(WIN32) || defined(__EMX__)
41# include <io.h>
42#else
43# include <unistd.h>
44#endif /* WIN32 || __EMX__ */
45
f7deaa1a 46#if HAVE_AUTHORIZATION_H
47# include <Security/Authorization.h>
48# ifdef HAVE_SECBASEPRIV_H
49# include <Security/SecBasePriv.h>
50# else
51extern const char *cssmErrorString(int error);
52# endif /* HAVE_SECBASEPRIV_H */
53#endif /* HAVE_AUTHORIZATION_H */
54
bc44d920 55#if defined(SO_PEERCRED) && defined(AF_LOCAL)
56# include <pwd.h>
57#endif /* SO_PEERCRED && AF_LOCAL */
58
ef416fc2 59
60/*
61 * Local functions...
62 */
63
f7deaa1a 64#ifdef HAVE_GSSAPI
e07d4801 65static gss_name_t cups_get_gssname(http_t *http, const char *service_name);
f7deaa1a 66# ifdef DEBUG
e07d4801
MS
67static void cups_gss_printf(OM_uint32 major_status, OM_uint32 minor_status,
68 const char *message);
355e94dc 69# else
e07d4801
MS
70# define cups_gss_printf(major, minor, message)
71# endif /* DEBUG */
f7deaa1a 72#endif /* HAVE_GSSAPI */
ef416fc2 73static int cups_local_auth(http_t *http);
74
75
76/*
77 * 'cupsDoAuthentication()' - Authenticate a request.
78 *
5a738aea 79 * This function should be called in response to a @code HTTP_UNAUTHORIZED@
ef416fc2 80 * status, prior to resubmitting your request.
81 *
426c6a59 82 * @since CUPS 1.1.20/Mac OS X 10.4@
ef416fc2 83 */
84
85int /* O - 0 on success, -1 on error */
568fa3fa 86cupsDoAuthentication(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
5a738aea 87 const char *method,/* I - Request method ("GET", "POST", "PUT") */
ef416fc2 88 const char *resource)
89 /* I - Resource path */
90{
91 const char *password; /* Password string */
92 char prompt[1024], /* Prompt for user */
93 realm[HTTP_MAX_VALUE], /* realm="xyz" string */
5a738aea 94 nonce[HTTP_MAX_VALUE]; /* nonce="xyz" string */
f7deaa1a 95 int localauth; /* Local authentication result */
b86bc4cf 96 _cups_globals_t *cg; /* Global data */
ef416fc2 97
98
e07d4801 99 DEBUG_printf(("cupsDoAuthentication(http=%p, method=\"%s\", resource=\"%s\")",
ef416fc2 100 http, method, resource));
e07d4801 101 DEBUG_printf(("2cupsDoAuthentication: digest_tries=%d, userpass=\"%s\"",
ef416fc2 102 http->digest_tries, http->userpass));
e07d4801 103 DEBUG_printf(("2cupsDoAuthentication: WWW-Authenticate=\"%s\"",
07725fee 104 httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE)));
ef416fc2 105
106 /*
107 * Clear the current authentication string...
108 */
109
355e94dc 110 httpSetAuthString(http, NULL, NULL);
ef416fc2 111
112 /*
113 * See if we can do local authentication...
114 */
115
f7deaa1a 116 if (http->digest_tries < 3)
ef416fc2 117 {
f7deaa1a 118 if ((localauth = cups_local_auth(http)) == 0)
119 {
e07d4801 120 DEBUG_printf(("2cupsDoAuthentication: authstring=\"%s\"",
f7deaa1a 121 http->authstring));
122
123 if (http->status == HTTP_UNAUTHORIZED)
124 http->digest_tries ++;
125
126 return (0);
127 }
128 else if (localauth == -1)
129 return (-1); /* Error or canceled */
ef416fc2 130 }
131
132 /*
133 * Nope, see if we should retry the current username:password...
134 */
135
f7deaa1a 136 if ((http->digest_tries > 1 || !http->userpass[0]) &&
137 strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Negotiate", 9))
ef416fc2 138 {
139 /*
140 * Nope - get a new password from the user...
141 */
142
b86bc4cf 143 cg = _cupsGlobals();
144
145 if (!cg->lang_default)
146 cg->lang_default = cupsLangDefault();
147
148 snprintf(prompt, sizeof(prompt),
149 _cupsLangString(cg->lang_default, _("Password for %s on %s? ")),
150 cupsUser(),
151 http->hostname[0] == '/' ? "localhost" : http->hostname);
ef416fc2 152
153 http->digest_tries = strncasecmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE],
154 "Digest", 5) != 0;
155 http->userpass[0] = '\0';
156
157 if ((password = cupsGetPassword(prompt)) == NULL)
158 return (-1);
159
160 if (!password[0])
161 return (-1);
162
163 snprintf(http->userpass, sizeof(http->userpass), "%s:%s", cupsUser(),
164 password);
165 }
166 else if (http->status == HTTP_UNAUTHORIZED)
167 http->digest_tries ++;
168
169 /*
170 * Got a password; encode it for the server...
171 */
172
f7deaa1a 173 if (!strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Negotiate", 9))
174 {
175#ifdef HAVE_GSSAPI
176 /*
177 * Kerberos authentication...
178 */
179
180 OM_uint32 minor_status, /* Minor status code */
181 major_status; /* Major status code */
182 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER,
183 /* Output token */
184 input_token = GSS_C_EMPTY_BUFFER;
185 /* Input token */
186 char *gss_service_name;
187 /* GSS service name */
355e94dc 188# ifdef USE_SPNEGO
f7deaa1a 189 const char *authorization;
190 /* Pointer into Authorization string */
355e94dc 191# endif /* USE_SPNEGO */
f7deaa1a 192
193
f42414bf 194# ifdef __APPLE__
195 /*
196 * If the weak-linked GSSAPI/Kerberos library is not present, don't try
197 * to use it...
198 */
199
200 if (gss_init_sec_context == NULL)
201 {
e07d4801 202 DEBUG_puts("1cupsDoAuthentication: Weak-linked GSSAPI/Kerberos framework "
f42414bf 203 "is not present");
204 return (-1);
205 }
206# endif /* __APPLE__ */
207
355e94dc
MS
208 if (http->status == HTTP_UNAUTHORIZED && http->digest_tries >= 3)
209 {
e07d4801 210 DEBUG_printf(("1cupsDoAuthentication: too many Negotiate tries (%d)",
355e94dc
MS
211 http->digest_tries));
212
213 return (-1);
214 }
215
f7deaa1a 216 if (http->gssname == GSS_C_NO_NAME)
217 {
218 if ((gss_service_name = getenv("CUPS_GSSSERVICENAME")) == NULL)
219 gss_service_name = CUPS_DEFAULT_GSSSERVICENAME;
220 else
e07d4801
MS
221 DEBUG_puts("2cupsDoAuthentication: GSS service name set via "
222 "environment variable");
f7deaa1a 223
e07d4801 224 http->gssname = cups_get_gssname(http, gss_service_name);
f7deaa1a 225 }
226
355e94dc 227# ifdef USE_SPNEGO /* We don't implement SPNEGO just yet... */
f7deaa1a 228 /*
229 * Find the start of the Kerberos input token...
230 */
231
232 authorization = httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE);
233
234 authorization += 9;
235 while (*authorization && isspace(*authorization & 255))
236 authorization ++;
237
238 if (*authorization)
239 {
240 /*
355e94dc 241 * Decode the authorization string to get the input token...
f7deaa1a 242 */
355e94dc
MS
243
244 int len = strlen(authorization);
245
246 input_token.value = malloc(len);
247 input_token.value = httpDecode64_2(input_token.value, &len,
248 authorization);
249 input_token.length = len;
250
251# ifdef DEBUG
252 {
253 char *ptr = (char *)input_token.value;
254 int left = len;
255
256 fputs("input_token=", stdout);
257 while (left > 0)
258 {
259 if (*ptr < ' ')
260 printf("\\%03o", *ptr & 255);
261 else
262 putchar(*ptr);
263 ptr ++;
264 left --;
265 }
266 putchar('\n');
267 }
268# endif /* DEBUG */
f7deaa1a 269 }
355e94dc 270# endif /* USE_SPNEGO */
bc44d920 271
272 if (http->gssctx != GSS_C_NO_CONTEXT)
f7deaa1a 273 {
1f0275e3 274 gss_delete_sec_context(&minor_status, &http->gssctx, GSS_C_NO_BUFFER);
bc44d920 275 http->gssctx = GSS_C_NO_CONTEXT;
f7deaa1a 276 }
277
278 major_status = gss_init_sec_context(&minor_status, GSS_C_NO_CREDENTIAL,
279 &http->gssctx,
280 http->gssname, http->gssmech,
e07d4801
MS
281#ifdef GSS_C_DELEG_POLICY_FLAG
282 GSS_C_DELEG_POLICY_FLAG |
283#endif /* GSS_C_DELEG_POLICY_FLAG */
284 GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG,
bc44d920 285 GSS_C_INDEFINITE,
f7deaa1a 286 GSS_C_NO_CHANNEL_BINDINGS,
287 &input_token, &http->gssmech,
288 &output_token, NULL, NULL);
289
290 if (input_token.value)
291 free(input_token.value);
292
293 if (GSS_ERROR(major_status))
294 {
e07d4801
MS
295 cups_gss_printf(major_status, minor_status,
296 "cupsDoAuthentication: Unable to initialize security "
297 "context");
f7deaa1a 298 return (-1);
299 }
300
f7deaa1a 301 if (major_status == GSS_S_CONTINUE_NEEDED)
e07d4801
MS
302 cups_gss_printf(major_status, minor_status,
303 "cupsDoAuthentication: Continuation needed!");
f7deaa1a 304
5a738aea 305 if (output_token.length > 0 && output_token.length <= 65536)
f7deaa1a 306 {
5a738aea
MS
307 /*
308 * Allocate the authorization string since Windows KDCs can have
309 * arbitrarily large credentials...
310 */
311
312 int authsize = 10 + /* "Negotiate " */
313 output_token.length * 4 / 3 + 1 + /* Base64 */
314 1; /* nul */
315
316 httpSetAuthString(http, NULL, NULL);
317
318 if ((http->authstring = malloc(authsize)) == NULL)
319 {
320 http->authstring = http->_authstring;
321 authsize = sizeof(http->_authstring);
322 }
323
324 strcpy(http->authstring, "Negotiate ");
325 httpEncode64_2(http->authstring + 10, authsize - 10, output_token.value,
f7deaa1a 326 output_token.length);
f7deaa1a 327
1f0275e3 328 gss_release_buffer(&minor_status, &output_token);
f7deaa1a 329 }
5a738aea
MS
330 else
331 {
e07d4801
MS
332 DEBUG_printf(("1cupsDoAuthentication: Kerberos credentials too large - "
333 "%d bytes!", (int)output_token.length));
5a738aea 334
1f0275e3 335 gss_release_buffer(&minor_status, &output_token);
5a738aea
MS
336
337 return (-1);
338 }
f7deaa1a 339#endif /* HAVE_GSSAPI */
340 }
341 else if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Digest", 6))
ef416fc2 342 {
343 /*
344 * Basic authentication...
345 */
346
5a738aea
MS
347 char encode[256]; /* Base64 buffer */
348
349
ef416fc2 350 httpEncode64_2(encode, sizeof(encode), http->userpass,
b86bc4cf 351 (int)strlen(http->userpass));
355e94dc 352 httpSetAuthString(http, "Basic", encode);
ef416fc2 353 }
354 else
355 {
356 /*
357 * Digest authentication...
358 */
359
5a738aea
MS
360 char encode[33], /* MD5 buffer */
361 digest[1024]; /* Digest auth data */
355e94dc
MS
362
363
ef416fc2 364 httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "realm", realm);
365 httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "nonce", nonce);
366
367 httpMD5(cupsUser(), realm, strchr(http->userpass, ':') + 1, encode);
368 httpMD5Final(nonce, method, resource, encode);
355e94dc
MS
369 snprintf(digest, sizeof(digest),
370 "username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", "
371 "response=\"%s\"", cupsUser(), realm, nonce, resource, encode);
372 httpSetAuthString(http, "Digest", digest);
ef416fc2 373 }
374
e07d4801 375 DEBUG_printf(("1cupsDoAuthentication: authstring=\"%s\"", http->authstring));
ef416fc2 376
377 return (0);
378}
379
380
f7deaa1a 381#ifdef HAVE_GSSAPI
f7deaa1a 382/*
e07d4801 383 * 'cups_get_gssname()' - Get CUPS service credentials for authentication.
f7deaa1a 384 */
385
386static gss_name_t /* O - Server name */
e07d4801 387cups_get_gssname(
f7deaa1a 388 http_t *http, /* I - Connection to server */
389 const char *service_name) /* I - Service name */
390{
391 gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
392 /* Service token */
bc44d920 393 OM_uint32 major_status, /* Major status code */
394 minor_status; /* Minor status code */
395 gss_name_t server_name; /* Server name */
396 char buf[1024], /* Name buffer */
397 fqdn[HTTP_MAX_URI]; /* Server name buffer */
398
399
e07d4801
MS
400 DEBUG_printf(("7cups_get_gssname(http=%p, service_name=\"%s\")", http,
401 service_name));
402
403
bc44d920 404 /*
405 * Get the hostname...
406 */
f7deaa1a 407
bc44d920 408 httpGetHostname(http, fqdn, sizeof(fqdn));
409
410 if (!strcmp(fqdn, "localhost"))
411 httpGetHostname(NULL, fqdn, sizeof(fqdn));
f7deaa1a 412
413 /*
414 * Get a server name we can use for authentication purposes...
415 */
416
bc44d920 417 snprintf(buf, sizeof(buf), "%s@%s", service_name, fqdn);
f7deaa1a 418
e07d4801 419 DEBUG_printf(("9cups_get_gssname: Looking up %s...", buf));
7ff4fea9 420
f7deaa1a 421 token.value = buf;
422 token.length = strlen(buf);
423 server_name = GSS_C_NO_NAME;
424 major_status = gss_import_name(&minor_status, &token,
425 GSS_C_NT_HOSTBASED_SERVICE,
426 &server_name);
427
428 if (GSS_ERROR(major_status))
429 {
e07d4801
MS
430 cups_gss_printf(major_status, minor_status,
431 "cups_get_gssname: gss_import_name() failed");
f7deaa1a 432 return (NULL);
433 }
434
435 return (server_name);
436}
e07d4801
MS
437
438
439# ifdef DEBUG
440/*
441 * 'cups_gss_printf()' - Show debug error messages from GSSAPI...
442 */
443
444static void
445cups_gss_printf(OM_uint32 major_status,/* I - Major status code */
446 OM_uint32 minor_status,/* I - Minor status code */
447 const char *message) /* I - Prefix for error message */
448{
449 OM_uint32 err_major_status, /* Major status code for display */
450 err_minor_status; /* Minor status code for display */
451 OM_uint32 msg_ctx; /* Message context */
452 gss_buffer_desc major_status_string = GSS_C_EMPTY_BUFFER,
453 /* Major status message */
454 minor_status_string = GSS_C_EMPTY_BUFFER;
455 /* Minor status message */
456
457
458 msg_ctx = 0;
459 err_major_status = gss_display_status(&err_minor_status,
460 major_status,
461 GSS_C_GSS_CODE,
462 GSS_C_NO_OID,
463 &msg_ctx,
464 &major_status_string);
465
466 if (!GSS_ERROR(err_major_status))
467 gss_display_status(&err_minor_status, minor_status, GSS_C_MECH_CODE,
468 GSS_C_NULL_OID, &msg_ctx, &minor_status_string);
469
470 DEBUG_printf(("8%s: %s, %s", message, (char *)major_status_string.value,
471 (char *)minor_status_string.value));
472
473 gss_release_buffer(&err_minor_status, &major_status_string);
474 gss_release_buffer(&err_minor_status, &minor_status_string);
475}
476# endif /* DEBUG */
f7deaa1a 477#endif /* HAVE_GSSAPI */
478
479
ef416fc2 480/*
481 * 'cups_local_auth()' - Get the local authorization certificate if
482 * available/applicable...
483 */
484
f7deaa1a 485static int /* O - 0 if available */
bc44d920 486 /* 1 if not available */
f7deaa1a 487 /* -1 error */
ef416fc2 488cups_local_auth(http_t *http) /* I - HTTP connection to server */
489{
490#if defined(WIN32) || defined(__EMX__)
491 /*
492 * Currently WIN32 and OS-2 do not support the CUPS server...
493 */
494
bc44d920 495 return (1);
ef416fc2 496#else
f7deaa1a 497 int pid; /* Current process ID */
498 FILE *fp; /* Certificate file */
e07d4801
MS
499 char trc[16], /* Try Root Certificate parameter */
500 filename[1024], /* Certificate filename */
f7deaa1a 501 certificate[33];/* Certificate string */
ef416fc2 502 _cups_globals_t *cg = _cupsGlobals(); /* Global data */
bc44d920 503# if defined(HAVE_AUTHORIZATION_H)
f7deaa1a 504 OSStatus status; /* Status */
505 AuthorizationItem auth_right; /* Authorization right */
506 AuthorizationRights auth_rights; /* Authorization rights */
507 AuthorizationFlags auth_flags; /* Authorization flags */
508 AuthorizationExternalForm auth_extrn; /* Authorization ref external */
509 char auth_key[1024]; /* Buffer */
510 char buffer[1024]; /* Buffer */
bc44d920 511# endif /* HAVE_AUTHORIZATION_H */
ef416fc2 512
513
e07d4801 514 DEBUG_printf(("7cups_local_auth(http=%p) hostaddr=%s, hostname=\"%s\"",
ef416fc2 515 http, httpAddrString(http->hostaddr, filename, sizeof(filename)), http->hostname));
516
517 /*
518 * See if we are accessing localhost...
519 */
520
521 if (!httpAddrLocalhost(http->hostaddr) &&
522 strcasecmp(http->hostname, "localhost") != 0)
523 {
e07d4801 524 DEBUG_puts("8cups_local_auth: Not a local connection!");
bc44d920 525 return (1);
ef416fc2 526 }
527
bc44d920 528# if defined(HAVE_AUTHORIZATION_H)
f7deaa1a 529 /*
530 * Delete any previous authorization reference...
531 */
532
b94498cf 533 if (http->auth_ref)
f7deaa1a 534 {
b94498cf 535 AuthorizationFree(http->auth_ref, kAuthorizationFlagDefaults);
536 http->auth_ref = NULL;
f7deaa1a 537 }
538
e4572d57
MS
539 if (!getenv("GATEWAY_INTERFACE") &&
540 httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "authkey",
f7deaa1a 541 auth_key, sizeof(auth_key)))
542 {
543 status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment,
b94498cf 544 kAuthorizationFlagDefaults, &http->auth_ref);
f7deaa1a 545 if (status != errAuthorizationSuccess)
546 {
e07d4801 547 DEBUG_printf(("8cups_local_auth: AuthorizationCreate() returned %d (%s)",
f7deaa1a 548 (int)status, cssmErrorString(status)));
549 return (-1);
550 }
551
552 auth_right.name = auth_key;
553 auth_right.valueLength = 0;
554 auth_right.value = NULL;
555 auth_right.flags = 0;
556
557 auth_rights.count = 1;
558 auth_rights.items = &auth_right;
559
560 auth_flags = kAuthorizationFlagDefaults |
561 kAuthorizationFlagPreAuthorize |
562 kAuthorizationFlagInteractionAllowed |
563 kAuthorizationFlagExtendRights;
564
b94498cf 565 status = AuthorizationCopyRights(http->auth_ref, &auth_rights,
f7deaa1a 566 kAuthorizationEmptyEnvironment,
567 auth_flags, NULL);
568 if (status == errAuthorizationSuccess)
b94498cf 569 status = AuthorizationMakeExternalForm(http->auth_ref, &auth_extrn);
f7deaa1a 570
571 if (status == errAuthorizationSuccess)
572 {
573 /*
574 * Set the authorization string and return...
575 */
576
577 httpEncode64_2(buffer, sizeof(buffer), (void *)&auth_extrn,
578 sizeof(auth_extrn));
579
355e94dc 580 httpSetAuthString(http, "AuthRef", buffer);
f7deaa1a 581
e07d4801 582 DEBUG_printf(("8cups_local_auth: Returning authstring=\"%s\"",
f7deaa1a 583 http->authstring));
584 return (0);
585 }
586 else if (status == errAuthorizationCanceled)
587 return (-1);
588
e07d4801 589 DEBUG_printf(("9cups_local_auth: AuthorizationCopyRights() returned %d (%s)",
f7deaa1a 590 (int)status, cssmErrorString(status)));
591
592 /*
593 * Fall through to try certificates...
594 */
595 }
bc44d920 596# endif /* HAVE_AUTHORIZATION_H */
f7deaa1a 597
ef416fc2 598 /*
599 * Try opening a certificate file for this PID. If that fails,
600 * try the root certificate...
601 */
602
603 pid = getpid();
604 snprintf(filename, sizeof(filename), "%s/certs/%d", cg->cups_statedir, pid);
605 if ((fp = fopen(filename, "r")) == NULL && pid > 0)
606 {
bc44d920 607 /*
e07d4801 608 * No certificate for this PID; see if we can get the root certificate...
bc44d920 609 */
610
e07d4801
MS
611 DEBUG_printf(("9cups_local_auth: Unable to open file %s: %s",
612 filename, strerror(errno)));
613
614#ifdef HAVE_GSSAPI
355e94dc 615 if (!strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Negotiate", 9))
bc44d920 616 {
617 /*
e07d4801 618 * Kerberos required, don't try the root certificate...
bc44d920 619 */
620
621 return (1);
622 }
623#endif /* HAVE_GSSAPI */
624
e07d4801
MS
625 if (!httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "trc", trc,
626 sizeof(trc)))
627 {
628 /*
629 * Scheduler doesn't want us to use the root certificate...
630 */
631
632 return (1);
633 }
634
ef416fc2 635 snprintf(filename, sizeof(filename), "%s/certs/0", cg->cups_statedir);
636 fp = fopen(filename, "r");
637 }
638
f7deaa1a 639 if (fp)
ef416fc2 640 {
f7deaa1a 641 /*
642 * Read the certificate from the file...
643 */
ef416fc2 644
f7deaa1a 645 fgets(certificate, sizeof(certificate), fp);
646 fclose(fp);
ef416fc2 647
f7deaa1a 648 /*
649 * Set the authorization string and return...
650 */
ef416fc2 651
355e94dc 652 httpSetAuthString(http, "Local", certificate);
ef416fc2 653
e07d4801 654 DEBUG_printf(("8cups_local_auth: Returning authstring=\"%s\"",
f7deaa1a 655 http->authstring));
ef416fc2 656
f7deaa1a 657 return (0);
658 }
659
bc44d920 660# if defined(SO_PEERCRED) && defined(AF_LOCAL)
661 /*
662 * See if we can authenticate using the peer credentials provided over a
663 * domain socket; if so, specify "PeerCred username" as the authentication
664 * information...
665 */
666
667 if (http->hostaddr->addr.sa_family == AF_LOCAL &&
668 !getenv("GATEWAY_INTERFACE")) /* Not via CGI programs... */
669 {
670 /*
671 * Verify that the current cupsUser() matches the current UID...
672 */
673
674 struct passwd *pwd; /* Password information */
675 const char *username; /* Current username */
676
677 username = cupsUser();
678
679 if ((pwd = getpwnam(username)) != NULL && pwd->pw_uid == getuid())
680 {
355e94dc 681 httpSetAuthString(http, "PeerCred", username);
bc44d920 682
e07d4801 683 DEBUG_printf(("8cups_local_auth: Returning authstring=\"%s\"",
bc44d920 684 http->authstring));
685
686 return (0);
687 }
688 }
689# endif /* SO_PEERCRED && AF_LOCAL */
690
f7deaa1a 691 return (1);
ef416fc2 692#endif /* WIN32 || __EMX__ */
693}
694
695
696/*
b19ccc9e 697 * End of "$Id: auth.c 7720 2008-07-11 22:46:21Z mike $".
ef416fc2 698 */