]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/usersys.c
Merge changes from CUPS 1.4svn-r8540.
[thirdparty/cups.git] / cups / usersys.c
CommitLineData
ef416fc2 1/*
e07d4801 2 * "$Id: usersys.c 8498 2009-04-13 17:03:15Z mike $"
ef416fc2 3 *
4 * User, system, and password routines for the Common UNIX Printing
5 * System (CUPS).
6 *
e07d4801 7 * Copyright 2007-2009 by Apple Inc.
ef416fc2 8 * Copyright 1997-2006 by Easy Software Products.
9 *
10 * These coded instructions, statements, and computer programs are the
bc44d920 11 * property of Apple Inc. and are protected by Federal copyright
12 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
13 * which should have been included with this file. If this file is
14 * file is missing or damaged, see the license at "http://www.cups.org/".
ef416fc2 15 *
16 * This file is subject to the Apple OS-Developed Software exception.
17 *
18 * Contents:
19 *
b423cd4c 20 * cupsEncryption() - Get the default encryption settings.
21 * cupsGetPassword() - Get a password from the user.
e07d4801
MS
22 * cupsServer() - Return the hostname/address of the default
23 * server.
b423cd4c 24 * cupsSetEncryption() - Set the encryption preference.
25 * cupsSetPasswordCB() - Set the password callback for CUPS.
26 * cupsSetServer() - Set the default server name.
27 * cupsSetUser() - Set the default user name.
e07d4801 28 * cupsUser() - Return the current user's name.
b423cd4c 29 * _cupsGetPassword() - Get a password from the user.
e07d4801
MS
30 * _cupsSetDefaults() - Set the default server, port, and encryption.
31 * cups_read_client_conf() - Read a client.conf file.
ef416fc2 32 */
33
34/*
35 * Include necessary headers...
36 */
37
38#include "http-private.h"
39#include "globals.h"
40#include <stdlib.h>
e00b005a 41#include <sys/stat.h>
ef416fc2 42#ifdef WIN32
43# include <windows.h>
44#endif /* WIN32 */
d09495fa 45#include "debug.h"
ef416fc2 46
47
b423cd4c 48/*
49 * Local functions...
50 */
51
e07d4801
MS
52static void cups_read_client_conf(cups_file_t *fp,
53 _cups_globals_t *cg,
54 const char *cups_encryption,
55 const char *cups_server);
b423cd4c 56
57
ef416fc2 58/*
59 * 'cupsEncryption()' - Get the default encryption settings.
60 *
61 * The default encryption setting comes from the CUPS_ENCRYPTION
568fa3fa 62 * environment variable, then the ~/.cups/client.conf file, and finally the
ef416fc2 63 * /etc/cups/client.conf file. If not set, the default is
5a738aea 64 * @code HTTP_ENCRYPT_IF_REQUESTED@.
ef416fc2 65 */
66
67http_encryption_t /* O - Encryption settings */
68cupsEncryption(void)
69{
ef416fc2 70 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
71
72
ef416fc2 73 if (cg->encryption == (http_encryption_t)-1)
e07d4801 74 _cupsSetDefaults();
ef416fc2 75
76 return (cg->encryption);
77}
78
79
80/*
81 * 'cupsGetPassword()' - Get a password from the user.
82 *
5a738aea 83 * Uses the current password callback function. Returns @code NULL@ if the
ecdc0628 84 * user does not provide a password.
ef416fc2 85 */
86
87const char * /* O - Password */
88cupsGetPassword(const char *prompt) /* I - Prompt string */
89{
90 return ((*_cupsGlobals()->password_cb)(prompt));
91}
92
93
ef416fc2 94/*
95 * 'cupsServer()' - Return the hostname/address of the default server.
96 *
97 * The returned value can be a fully-qualified hostname, a numeric
98 * IPv4 or IPv6 address, or a domain socket pathname.
99 */
100
101const char * /* O - Server name */
102cupsServer(void)
103{
ef416fc2 104 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
105
106
ef416fc2 107 if (!cg->server[0])
e07d4801 108 _cupsSetDefaults();
ef416fc2 109
e07d4801
MS
110 return (cg->server);
111}
ef416fc2 112
d09495fa 113
e07d4801
MS
114/*
115 * 'cupsSetEncryption()' - Set the encryption preference.
116 */
ef416fc2 117
e07d4801
MS
118void
119cupsSetEncryption(http_encryption_t e) /* I - New encryption preference */
120{
121 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
ef416fc2 122
ef416fc2 123
e07d4801 124 cg->encryption = e;
ef416fc2 125
e07d4801
MS
126 if (cg->http)
127 httpEncryption(cg->http, e);
ef416fc2 128}
129
130
131/*
132 * 'cupsSetPasswordCB()' - Set the password callback for CUPS.
133 *
5a738aea 134 * Pass @code NULL@ to restore the default (console) password callback.
ef416fc2 135 */
136
137void
138cupsSetPasswordCB(cups_password_cb_t cb)/* I - Callback function */
139{
140 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
141
142
143 if (cb == (const char *(*)(const char *))0)
144 cg->password_cb = _cupsGetPassword;
145 else
146 cg->password_cb = cb;
147}
148
149
150/*
151 * 'cupsSetServer()' - Set the default server name.
152 *
153 * The "server" string can be a fully-qualified hostname, a numeric
5a738aea 154 * IPv4 or IPv6 address, or a domain socket pathname. Pass @code NULL@ to
ef416fc2 155 * restore the default server name.
156 */
157
158void
159cupsSetServer(const char *server) /* I - Server name */
160{
161 char *port; /* Pointer to port */
162 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
163
164
165 if (server)
166 {
167 strlcpy(cg->server, server, sizeof(cg->server));
168
169 if (cg->server[0] != '/' && (port = strrchr(cg->server, ':')) != NULL &&
170 !strchr(port, ']') && isdigit(port[1] & 255))
171 {
172 *port++ = '\0';
173
e07d4801 174 cg->ipp_port = atoi(port);
ef416fc2 175 }
176
177 if (cg->server[0] == '/')
178 strcpy(cg->servername, "localhost");
179 else
180 strlcpy(cg->servername, cg->server, sizeof(cg->servername));
181 }
182 else
183 {
184 cg->server[0] = '\0';
185 cg->servername[0] = '\0';
186 }
5a738aea
MS
187
188 if (cg->http)
189 {
190 httpClose(cg->http);
191 cg->http = NULL;
192 }
ef416fc2 193}
194
195
196/*
197 * 'cupsSetUser()' - Set the default user name.
198 *
5a738aea 199 * Pass @code NULL@ to restore the default user name.
ef416fc2 200 */
201
202void
203cupsSetUser(const char *user) /* I - User name */
204{
205 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
206
207
208 if (user)
209 strlcpy(cg->user, user, sizeof(cg->user));
210 else
211 cg->user[0] = '\0';
212}
213
214
215#if defined(WIN32)
216/*
217 * WIN32 username and password stuff.
218 */
219
220/*
221 * 'cupsUser()' - Return the current user's name.
222 */
223
224const char * /* O - User name */
225cupsUser(void)
226{
227 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
228
229
230 if (!cg->user[0])
231 {
232 DWORD size; /* Size of string */
233
234
235 size = sizeof(cg->user);
236 if (!GetUserName(cg->user, &size))
237 {
238 /*
239 * Use the default username...
240 */
241
242 strcpy(cg->user, "unknown");
243 }
244 }
245
246 return (cg->user);
247}
248
249
250/*
251 * '_cupsGetPassword()' - Get a password from the user.
252 */
253
254const char * /* O - Password */
255_cupsGetPassword(const char *prompt) /* I - Prompt string */
256{
257 return (NULL);
258}
259#else
260/*
261 * UNIX username and password stuff...
262 */
263
264# include <pwd.h>
265
266/*
267 * 'cupsUser()' - Return the current user's name.
268 */
269
270const char * /* O - User name */
271cupsUser(void)
272{
273 struct passwd *pwd; /* User/password entry */
274 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
275
276
277 if (!cg->user[0])
278 {
279 /*
280 * Rewind the password file...
281 */
282
283 setpwent();
284
285 /*
286 * Lookup the password entry for the current user.
287 */
288
289 if ((pwd = getpwuid(getuid())) == NULL)
290 strcpy(cg->user, "unknown"); /* Unknown user! */
291 else
292 {
293 /*
294 * Copy the username...
295 */
296
297 setpwent();
298
299 strlcpy(cg->user, pwd->pw_name, sizeof(cg->user));
300 }
301
302 /*
303 * Rewind the password file again...
304 */
305
306 setpwent();
307 }
308
309 return (cg->user);
310}
311
312
313/*
314 * '_cupsGetPassword()' - Get a password from the user.
315 */
316
317const char * /* O - Password */
318_cupsGetPassword(const char *prompt) /* I - Prompt string */
319{
320 return (getpass(prompt));
321}
322#endif /* WIN32 */
323
324
325/*
e07d4801 326 * '_cupsSetDefaults()' - Set the default server, port, and encryption.
b423cd4c 327 */
328
e07d4801
MS
329void
330_cupsSetDefaults(void)
b423cd4c 331{
332 cups_file_t *fp; /* File */
e07d4801
MS
333 const char *home, /* Home directory of user */
334 *cups_encryption, /* CUPS_ENCRYPTION env var */
335 *cups_server; /* CUPS_SERVER env var */
b423cd4c 336 char filename[1024]; /* Filename */
337 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
338
339
e07d4801
MS
340 DEBUG_puts("_cupsSetDefaults()");
341
342 /*
343 * First collect environment variables...
344 */
345
346 cups_encryption = getenv("CUPS_ENCRYPTION");
347 cups_server = getenv("CUPS_SERVER");
348
349 /*
350 * Then, if needed, the .cups/client.conf or .cupsrc file in the home
351 * directory...
352 */
353
354 if ((cg->encryption == (http_encryption_t)-1 || !cg->server[0] ||
355 !cg->ipp_port) && (home = getenv("HOME")) != NULL)
b423cd4c 356 {
357 /*
358 * Look for ~/.cups/client.conf or ~/.cupsrc...
359 */
360
361 snprintf(filename, sizeof(filename), "%s/.cups/client.conf", home);
e07d4801 362 if ((fp = cupsFileOpen(filename, "r")) == NULL)
d09495fa 363 {
e07d4801
MS
364 snprintf(filename, sizeof(filename), "%s/.cupsrc", home);
365 fp = cupsFileOpen(filename, "r");
d09495fa 366 }
b423cd4c 367
e07d4801
MS
368 if (fp)
369 {
370 cups_read_client_conf(fp, cg, cups_encryption, cups_server);
371 cupsFileClose(fp);
372 }
373 }
374
375 if (cg->encryption == (http_encryption_t)-1 || !cg->server[0] ||
376 !cg->ipp_port)
377 {
378 /*
379 * Look for CUPS_SERVERROOT/client.conf...
380 */
381
382 snprintf(filename, sizeof(filename), "%s/client.conf", cg->cups_serverroot);
b423cd4c 383 if ((fp = cupsFileOpen(filename, "r")) != NULL)
d09495fa 384 {
e07d4801
MS
385 cups_read_client_conf(fp, cg, cups_encryption, cups_server);
386 cupsFileClose(fp);
387 }
388 }
389
390 /*
391 * If we still have things that aren't set, use the compiled in defaults...
392 */
393
394 if (cg->encryption == (http_encryption_t)-1)
395 cg->encryption = HTTP_ENCRYPT_IF_REQUESTED;
396
397 if (!cg->server[0])
398 {
399 if (!cups_server)
400 {
401#ifdef CUPS_DEFAULT_DOMAINSOCKET
402 /*
403 * If we are compiled with domain socket support, only use the
404 * domain socket if it exists and has the right permissions...
405 */
406
407 struct stat sockinfo; /* Domain socket information */
408
409 if (!stat(CUPS_DEFAULT_DOMAINSOCKET, &sockinfo) &&
410 (sockinfo.st_mode & S_IRWXO) == S_IRWXO)
411 cups_server = CUPS_DEFAULT_DOMAINSOCKET;
412 else
413#endif /* CUPS_DEFAULT_DOMAINSOCKET */
414 cups_server = "localhost";
415 }
416
417 cupsSetServer(cups_server);
418 }
419
420 if (!cg->ipp_port)
421 {
422 const char *ipp_port; /* IPP_PORT environment variable */
423 struct servent *service; /* Port number info */
424
425
426 if ((ipp_port = getenv("IPP_PORT")) != NULL)
427 {
428 if ((cg->ipp_port = atoi(ipp_port)) <= 0)
429 cg->ipp_port = CUPS_DEFAULT_IPP_PORT;
d09495fa 430 }
e07d4801
MS
431 else if ((service = getservbyname("ipp", NULL)) == NULL ||
432 service->s_port <= 0)
433 cg->ipp_port = CUPS_DEFAULT_IPP_PORT;
434 else
435 cg->ipp_port = ntohs(service->s_port);
436 }
437}
438
439
440/*
441 * 'cups_read_client_conf()' - Read a client.conf file.
442 */
443
444static void
445cups_read_client_conf(
446 cups_file_t *fp, /* I - File to read */
447 _cups_globals_t *cg, /* I - Global data */
448 const char *cups_encryption, /* I - CUPS_ENCRYPTION env var */
449 const char *cups_server) /* I - CUPS_SERVER env var */
450{
451 int linenum; /* Current line number */
452 char line[1024], /* Line from file */
453 *value, /* Pointer into line */
454 encryption[1024], /* Encryption value */
455 server_name[1024]; /* ServerName value */
456
457
458 /*
459 * Read from the file...
460 */
461
462 linenum = 0;
463 while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
464 {
465 if (!cups_encryption && cg->encryption == (http_encryption_t)-1 &&
466 !strcasecmp(line, "Encryption") && value)
467 {
468 strlcpy(encryption, value, sizeof(encryption));
469 cups_encryption = encryption;
470 }
471 else if (!cups_server && (!cg->server[0] || !cg->ipp_port) &&
472 !strcasecmp(line, "ServerName") && value)
473 {
474 strlcpy(server_name, value, sizeof(server_name));
475 cups_server = server_name;
476 }
477 }
478
479 /*
480 * Set values...
481 */
482
483 if (cg->encryption == (http_encryption_t)-1 && cups_encryption)
484 {
485 if (!strcasecmp(cups_encryption, "never"))
486 cg->encryption = HTTP_ENCRYPT_NEVER;
487 else if (!strcasecmp(cups_encryption, "always"))
488 cg->encryption = HTTP_ENCRYPT_ALWAYS;
489 else if (!strcasecmp(cups_encryption, "required"))
490 cg->encryption = HTTP_ENCRYPT_REQUIRED;
491 else
492 cg->encryption = HTTP_ENCRYPT_IF_REQUESTED;
b423cd4c 493 }
494
e07d4801
MS
495 if ((!cg->server[0] || !cg->ipp_port) && cups_server)
496 {
497 if (!cg->server[0])
498 {
499 /*
500 * Copy server name...
501 */
502
503 strlcpy(cg->server, cups_server, sizeof(cg->server));
504
505 if (cg->server[0] != '/' && (value = strrchr(cg->server, ':')) != NULL &&
506 !strchr(value, ']') && isdigit(value[1] & 255))
507 *value++ = '\0';
508 else
509 value = NULL;
510
511 if (cg->server[0] == '/')
512 strcpy(cg->servername, "localhost");
513 else
514 strlcpy(cg->servername, cg->server, sizeof(cg->servername));
515 }
516 else if (cups_server[0] != '/' &&
517 (value = strrchr(cups_server, ':')) != NULL &&
518 !strchr(value, ']') && isdigit(value[1] & 255))
519 value ++;
520 else
521 value = NULL;
522
523 if (!cg->ipp_port && value)
524 cg->ipp_port = atoi(value);
525 }
b423cd4c 526}
527
528
529/*
e07d4801 530 * End of "$Id: usersys.c 8498 2009-04-13 17:03:15Z mike $".
ef416fc2 531 */