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