273
/* Checks to see if specified directory exists, makes it if not
274
* Returns: 0 if already exists, 1 if created, < 0 if error occured
277
CheckServerAuthDir (const char *path, struct stat *statb, int mode)
279
int r = stat(path, statb);
282
if (errno == ENOENT) {
283
r = mkdir(path, mode);
285
LogError ("cannot make authentication directory %s: %s\n",
286
path, _SysErrorMsg (errno));
291
LogError ("cannot access authentication directory %s: %s\n",
292
path, _SysErrorMsg (errno));
294
} else { /* Directory already exists */
295
if (!S_ISDIR(statb->st_mode)) {
296
LogError ("cannot make authentication directory %s: %s\n",
297
path, "file with that name already exists");
273
305
static char authdir1[] = "authdir";
274
306
static char authdir2[] = "authfiles";
300
332
CleanUpFileName (d->name, cleanname, NAMELEN - 8);
334
/* Make authDir if it doesn't already exist */
335
r = CheckServerAuthDir(authDir, &statb, 0755);
301
340
len = strlen (authDir) + strlen (authdir1) + strlen (authdir2)
302
341
+ strlen (cleanname) + 14;
303
342
d->authFile = malloc (len);
307
346
snprintf (d->authFile, len, "%s/%s", authDir, authdir1);
308
r = stat(d->authFile, &statb);
347
r = CheckServerAuthDir(d->authFile, &statb, 0700);
310
349
if (statb.st_uid != 0)
311
350
(void) chown(d->authFile, 0, statb.st_gid);
312
351
if ((statb.st_mode & 0077) != 0)
313
352
(void) chmod(d->authFile, statb.st_mode & 0700);
315
if (errno == ENOENT) {
316
r = mkdir(d->authFile, 0700);
318
LogError ("cannot make authentication directory %s: "
319
"%s\n", d->authFile, _SysErrorMsg (errno));
322
LogError ("cannot access authentication directory %s: "
323
"%s\n", d->authFile, _SysErrorMsg (errno));
331
359
snprintf (d->authFile, len, "%s/%s/%s",
332
360
authDir, authdir1, authdir2);
333
r = mkdir(d->authFile, 0700);
334
if (r < 0 && errno != EEXIST) {
335
LogError ("cannot make authentication directory %s: %s\n",
336
d->authFile, _SysErrorMsg (errno));
361
r = CheckServerAuthDir(d->authFile, &statb, 0700);
337
363
free (d->authFile);
338
364
d->authFile = NULL;
384
413
if (!auth_file) {
385
Debug ("Can't creat auth file %s\n", d->authFile);
386
LogError ("Cannot open server authorization file %s\n", d->authFile);
414
LogError ("cannot open server authorization file %s: %s\n",
415
d->authFile, _SysErrorMsg (errno));
393
420
Debug ("File: %s auth: %p\n", d->authFile, auths);
425
* This is a crude hack to determine whether we really can
426
* write to the auth file even if we don't have real data
427
* to write right now.
431
* Write garbage data to file to provoke ENOSPC and other
434
(void) fprintf (auth_file, "%s", dummy_auth);
435
(void) fflush (auth_file);
436
if (ferror (auth_file))
442
* Rewind so that the garbage data is overwritten later.
395
446
for (i = 0; i < count; i++)
400
451
* to the auth file so xrdb and setup programs don't fail.
402
453
if (auths[i]->data_length > 0)
403
if (!XauWriteAuth (auth_file, auths[i]) ||
404
fflush (auth_file) == EOF)
406
LogError ("Cannot write server authorization file %s\n",
454
if (!XauWriteAuth (auth_file, auths[i]))
456
Debug ("XauWriteAuth() failed\n");
458
(void) fflush (auth_file);
459
if (ferror (auth_file))
466
* XXX: This is not elegant, but stdio has no truncation function.
468
if (ftruncate(fileno(auth_file), ftell(auth_file)))
470
Debug ("ftruncate() failed\n");
413
472
fclose (auth_file);
477
LogError ("Cannot write to server authorization file %s%s%s\n",
480
err ? _SysErrorMsg (errno) : "");
496
565
openFiles (char *name, char *new_name, FILE **oldp, FILE **newp)
500
570
strcpy (new_name, name);
501
571
strcat (new_name, "-n");
573
* Set safe umask for file creation operations.
502
575
mask = umask (0077);
577
* Unlink the authorization file we intend to create, and then open
578
* it with O_CREAT | O_EXCL to avoid race-based symlink attacks.
503
580
(void) unlink (new_name);
504
*newp = fopen (new_name, "w");
581
newfd = open (new_name, O_WRONLY | O_CREAT | O_EXCL, 0600);
583
*newp = fdopen (newfd, "w");
586
LogError ("Cannot create file %s: %s\n", new_name,
587
_SysErrorMsg (errno));
591
* There are no more attempts to create files after this point;
592
* restore the original umask.
505
594
(void) umask (mask);
507
596
Debug ("can't open new file %s\n", new_name);