]> git.ipfire.org Git - thirdparty/cups.git/blame - scheduler/cert.c
Load cups into easysw/current.
[thirdparty/cups.git] / scheduler / cert.c
CommitLineData
ef416fc2 1/*
fa73b229 2 * "$Id: cert.c 4966 2006-01-23 00:41:22Z mike $"
ef416fc2 3 *
4 * Authentication certificate routines for the Common UNIX
5 * Printing System (CUPS).
6 *
7 * Copyright 1997-2005 by Easy Software Products.
8 *
9 * These coded instructions, statements, and computer programs are the
10 * property of Easy Software Products and are protected by Federal
11 * copyright law. Distribution and use rights are outlined in the file
12 * "LICENSE.txt" which should have been included with this file. If this
13 * file is missing or damaged please contact Easy Software Products
14 * at:
15 *
16 * Attn: CUPS Licensing Information
17 * Easy Software Products
18 * 44141 Airport View Drive, Suite 204
19 * Hollywood, Maryland 20636 USA
20 *
21 * Voice: (301) 373-9600
22 * EMail: cups-info@cups.org
23 * WWW: http://www.cups.org
24 *
25 * Contents:
26 *
27 * cupsdAddCert() - Add a certificate.
28 * cupsdDeleteCert() - Delete a single certificate.
29 * cupsdDeleteAllCerts() - Delete all certificates...
30 * cupsdFindCert() - Find a certificate.
31 * cupsdInitCerts() - Initialize the certificate "system" and root
32 * certificate.
33 */
34
35/*
36 * Include necessary headers...
37 */
38
39#include "cupsd.h"
fa73b229 40#ifdef HAVE_ACL_INIT
41# include <sys/acl.h>
42# include <membership.h>
43#endif /* HAVE_ACL_INIT */
ef416fc2 44
45
46/*
47 * 'cupsdAddCert()' - Add a certificate.
48 */
49
50void
51cupsdAddCert(int pid, /* I - Process ID */
52 const char *username) /* I - Username */
53{
54 int i; /* Looping var */
55 cupsd_cert_t *cert; /* Current certificate */
56 int fd; /* Certificate file */
57 char filename[1024]; /* Certificate filename */
58 static const char hex[] = "0123456789ABCDEF";
59 /* Hex constants... */
60
61
62 cupsdLogMessage(CUPSD_LOG_DEBUG2,
63 "cupsdAddCert: adding certificate for pid %d", pid);
64
65 /*
66 * Allocate memory for the certificate...
67 */
68
69 if ((cert = calloc(sizeof(cupsd_cert_t), 1)) == NULL)
70 return;
71
72 /*
73 * Fill in the certificate information...
74 */
75
76 cert->pid = pid;
77 strlcpy(cert->username, username, sizeof(cert->username));
78
79 for (i = 0; i < 32; i ++)
80 cert->certificate[i] = hex[random() & 15];
81
82 /*
83 * Save the certificate to a file readable only by the User and Group
84 * (or root and SystemGroup for PID == 0)...
85 */
86
87 snprintf(filename, sizeof(filename), "%s/certs/%d", StateDir, pid);
88 unlink(filename);
89
90 if ((fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0400)) < 0)
91 {
92 cupsdLogMessage(CUPSD_LOG_ERROR,
93 "cupsdAddCert: Unable to create certificate file %s - %s",
94 filename, strerror(errno));
95 free(cert);
96 return;
97 }
98
99 if (pid == 0)
100 {
fa73b229 101#ifdef HAVE_ACL_INIT
102 acl_t acl; /* ACL information */
103 acl_entry_t entry; /* ACL entry */
104 acl_permset_t permset; /* Permissions */
105 uuid_t group; /* Group ID */
106#endif /* HAVE_ACL_INIT */
107
108
ef416fc2 109 /*
110 * Root certificate...
111 */
112
113 fchmod(fd, 0440);
114 fchown(fd, RunUser, SystemGroupIDs[0]);
115
fa73b229 116#ifdef HAVE_ACL_INIT
117 if (NumSystemGroups > 1)
118 {
119 /*
120 * Set POSIX ACLs for the root certificate so that all system
121 * groups can access it...
122 */
123
124 acl = acl_init(NumSystemGroups - 1);
125
126 for (i = 1; i < NumSystemGroups; i ++)
127 {
128 /*
129 * Add each group ID to the ACL...
130 */
131
132 acl_create_entry(&acl, &entry);
133 acl_get_permset(entry, &permset);
134 acl_add_perm(permset, ACL_READ_DATA);
135 acl_set_tag_type(entry, ACL_EXTENDED_ALLOW);
136 mbr_gid_to_uuid((gid_t)SystemGroupIDs[i], group);
137 acl_set_qualifier(entry, &group);
138 acl_set_permset(entry, permset);
139 }
140
141 if (acl_set_fd(fd, acl))
142 cupsdLogMessage(CUPSD_LOG_ERROR,
143 "Unable to set ACLs on root certificate \"%s\" - %s",
144 filename, strerror(errno));
145 acl_free(acl);
146 }
147#endif /* HAVE_ACL_INIT */
148
ef416fc2 149 RootCertTime = time(NULL);
150 }
151 else
152 {
153 /*
154 * CGI certificate...
155 */
156
157 fchmod(fd, 0400);
158 fchown(fd, User, Group);
159 }
160
161 DEBUG_printf(("ADD pid=%d, username=%s, cert=%s\n", pid, username,
162 cert->certificate));
163
164 write(fd, cert->certificate, strlen(cert->certificate));
165 close(fd);
166
167 /*
168 * Insert the certificate at the front of the list...
169 */
170
171 cert->next = Certs;
172 Certs = cert;
173}
174
175
176/*
177 * 'cupsdDeleteCert()' - Delete a single certificate.
178 */
179
180void
181cupsdDeleteCert(int pid) /* I - Process ID */
182{
183 cupsd_cert_t *cert, /* Current certificate */
184 *prev; /* Previous certificate */
185 char filename[1024]; /* Certificate file */
186
187
188 for (prev = NULL, cert = Certs; cert != NULL; prev = cert, cert = cert->next)
189 if (cert->pid == pid)
190 {
191 /*
192 * Remove this certificate from the list...
193 */
194
195 cupsdLogMessage(CUPSD_LOG_DEBUG2,
196 "cupsdDeleteCert: removing certificate for pid %d", pid);
197
198 DEBUG_printf(("DELETE pid=%d, username=%s, cert=%s\n", cert->pid,
199 cert->username, cert->certificate));
200
201 if (prev == NULL)
202 Certs = cert->next;
203 else
204 prev->next = cert->next;
205
206 free(cert);
207
208 /*
209 * Delete the file and return...
210 */
211
212 snprintf(filename, sizeof(filename), "%s/certs/%d", StateDir, pid);
213 if (unlink(filename))
214 cupsdLogMessage(CUPSD_LOG_ERROR,
215 "cupsdDeleteCert: Unable to remove %s!\n", filename);
216
217 return;
218 }
219}
220
221
222/*
223 * 'cupsdDeleteAllCerts()' - Delete all certificates...
224 */
225
226void
227cupsdDeleteAllCerts(void)
228{
229 cupsd_cert_t *cert, /* Current certificate */
230 *next; /* Next certificate */
231 char filename[1024]; /* Certificate file */
232
233
234 /*
235 * Loop through each certificate, deleting them...
236 */
237
238 for (cert = Certs; cert != NULL; cert = next)
239 {
240 /*
241 * Delete the file...
242 */
243
244 snprintf(filename, sizeof(filename), "%s/certs/%d", StateDir, cert->pid);
245 if (unlink(filename))
246 cupsdLogMessage(CUPSD_LOG_ERROR,
247 "cupsdDeleteAllCerts: Unable to remove %s!\n", filename);
248
249 /*
250 * Free memory...
251 */
252
253 next = cert->next;
254 free(cert);
255 }
256
257 Certs = NULL;
258}
259
260
261/*
262 * 'cupsdFindCert()' - Find a certificate.
263 */
264
265const char * /* O - Matching username or NULL */
266cupsdFindCert(const char *certificate) /* I - Certificate */
267{
268 cupsd_cert_t *cert; /* Current certificate */
269
270
271 DEBUG_printf(("cupsdFindCert(certificate=%s)\n", certificate));
272 for (cert = Certs; cert != NULL; cert = cert->next)
273 if (!strcasecmp(certificate, cert->certificate))
274 {
275 DEBUG_printf((" returning %s...\n", cert->username));
276 return (cert->username);
277 }
278
279 DEBUG_puts(" certificate not found!");
280
281 return (NULL);
282}
283
284
285/*
286 * 'cupsdInitCerts()' - Initialize the certificate "system" and root
287 * certificate.
288 */
289
290void
291cupsdInitCerts(void)
292{
293 cups_file_t *fp; /* /dev/random file */
294 unsigned seed; /* Seed for random number generator */
295 struct timeval tod; /* Time of day */
296
297
298 /*
299 * Initialize the random number generator using the random device or
300 * the current time, as available...
301 */
302
303 if ((fp = cupsFileOpen("/dev/urandom", "rb")) == NULL)
304 {
305 /*
306 * Get the time in usecs and use it as the initial seed...
307 */
308
309 gettimeofday(&tod, NULL);
310
311 seed = (unsigned)(tod.tv_sec + tod.tv_usec);
312 }
313 else
314 {
315 /*
316 * Read 4 random characters from the random device and use
317 * them as the seed...
318 */
319
320 seed = cupsFileGetChar(fp);
321 seed = (seed << 8) | cupsFileGetChar(fp);
322 seed = (seed << 8) | cupsFileGetChar(fp);
323 seed = (seed << 8) | cupsFileGetChar(fp);
324
325 cupsFileClose(fp);
326 }
327
328 srandom(seed);
329
330 /*
331 * Create a root certificate and return...
332 */
333
334 if (!RunUser)
335 cupsdAddCert(0, "root");
336}
337
338
339/*
fa73b229 340 * End of "$Id: cert.c 4966 2006-01-23 00:41:22Z mike $".
ef416fc2 341 */