~ubuntu-branches/ubuntu/quantal/xdm/quantal

« back to all changes in this revision

Viewing changes to auth.c

  • Committer: Bazaar Package Importer
  • Author(s): Julien Cristau
  • Date: 2010-04-19 20:55:56 UTC
  • mfrom: (1.1.9 upstream) (9.2.1 sid)
  • mto: This revision was merged to the branch mainline in revision 12.
  • Revision ID: james.westby@ubuntu.com-20100419205556-9tgxo1rdu2c7vy8y
Tags: 1:1.1.10-1
* New upstream release.
  - don't delete the pid file from child xdm processes, closes: #372114
  - clear the "Login incorrect" message properly on next login,
    closes: #525596.  Thanks, Martin Dickopp!
  - fix xdmcp with net.ipv6.bindv6only=1
* Patches merged upstream:
  - 02_xdm_zombie_no_error.diff
  - 15_xdm_openfiles.diff
  - 90_xdm_write_dummy_auth.diff
  - 91_xdm_saveserverauth_logging.diff
  - log_sourcing_better.diff
  - selinux_support.diff
  - storepid_rewrite.diff
* Xstartup: use id -u $USER, not id -u, since this script is run as root.
  See #118677.
* debian/rules: delete libtool m4 files on clean.
* Introduce virtual facility x-display-manager for insserv
  (closes: #554839).  Thanks, Jonas Meurer!
* debian/rules: kill gratuitous uses of $(CURDIR).
* debian/xdm.pam: @include common-* after pam_env and friends, so that we
  still set env vars if e.g. common-auth contains a 'sufficient' module
  (closes: #444483).
* debian/xdm.init: add Short-Description (closes: #510085).

Show diffs side-by-side

added added

removed removed

Lines of Context:
270
270
    *dst = '\0';
271
271
}
272
272
 
 
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
 
275
 */
 
276
static int
 
277
CheckServerAuthDir (const char *path, struct stat *statb, int mode)
 
278
{
 
279
    int r = stat(path, statb);
 
280
 
 
281
    if (r != 0) {
 
282
        if (errno == ENOENT) {
 
283
            r = mkdir(path, mode);
 
284
            if (r < 0) {
 
285
                LogError ("cannot make authentication directory %s: %s\n",
 
286
                          path, _SysErrorMsg (errno));
 
287
            } else {
 
288
                r = 1;
 
289
            }
 
290
        } else {
 
291
            LogError ("cannot access authentication directory %s: %s\n",
 
292
                      path, _SysErrorMsg (errno));
 
293
        }
 
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");
 
298
            return -1;
 
299
        }
 
300
    }
 
301
 
 
302
    return r;
 
303
}
 
304
 
273
305
static char authdir1[] = "authdir";
274
306
static char authdir2[] = "authfiles";
275
307
 
277
309
MakeServerAuthFile (struct display *d, FILE ** file)
278
310
{
279
311
    int len;
280
 
#if defined(SYSV) && !defined(SVR4)
281
 
# define NAMELEN        14
 
312
#ifdef MAXNAMELEN
 
313
# define NAMELEN        MAXNAMELEN
282
314
#else
283
315
# define NAMELEN        255
284
316
#endif
298
330
                return FALSE;
299
331
        } else {
300
332
            CleanUpFileName (d->name, cleanname, NAMELEN - 8);
 
333
 
 
334
            /* Make authDir if it doesn't already exist */
 
335
            r = CheckServerAuthDir(authDir, &statb, 0755);
 
336
            if (r < 0) {
 
337
                return FALSE;
 
338
            }
 
339
 
301
340
            len = strlen (authDir) + strlen (authdir1) + strlen (authdir2)
302
341
                + strlen (cleanname) + 14;
303
342
            d->authFile = malloc (len);
305
344
                return FALSE;
306
345
 
307
346
            snprintf (d->authFile, len, "%s/%s", authDir, authdir1);
308
 
            r = stat(d->authFile, &statb);
 
347
            r = CheckServerAuthDir(d->authFile, &statb, 0700);
309
348
            if (r == 0) {
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);
314
 
            } else {
315
 
                if (errno == ENOENT) {
316
 
                    r = mkdir(d->authFile, 0700);
317
 
                    if (r < 0) {
318
 
                        LogError ("cannot make authentication directory %s: "
319
 
                                  "%s\n", d->authFile, _SysErrorMsg (errno));
320
 
                    }
321
 
                } else {
322
 
                    LogError ("cannot access authentication directory %s: "
323
 
                              "%s\n", d->authFile, _SysErrorMsg (errno));
324
 
                }
325
 
                if (r < 0) {
326
 
                    free (d->authFile);
327
 
                    d->authFile = NULL;
328
 
                    return FALSE;
329
 
                }
 
353
            } else if (r < 0) {
 
354
                free (d->authFile);
 
355
                d->authFile = NULL;
 
356
                return FALSE;
330
357
            }
 
358
 
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);
 
362
            if (r < 0) {
337
363
                free (d->authFile);
338
364
                d->authFile = NULL;
339
365
                return FALSE;
375
401
    mode_t      mask;
376
402
    int         ret;
377
403
    int         i;
 
404
    const char  dummy_auth[] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
 
405
                               "XXXXXXXXXXXXXXXXX"; /* 64 "X"s */
 
406
    int         err = 0;
378
407
 
379
408
    mask = umask (0077);
380
409
    ret = MakeServerAuthFile(d, &auth_file);
382
411
    if (!ret)
383
412
        return FALSE;
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);
387
 
        free (d->authFile);
388
 
        d->authFile = NULL;
 
414
        LogError ("cannot open server authorization file %s: %s\n",
 
415
                  d->authFile, _SysErrorMsg (errno));
389
416
        ret = FALSE;
390
417
    }
391
418
    else
392
419
    {
393
420
        Debug ("File: %s auth: %p\n", d->authFile, auths);
394
421
        ret = TRUE;
 
422
        if (count == 0)
 
423
        {
 
424
                /*
 
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.
 
428
                 */
 
429
 
 
430
                /*
 
431
                 * Write garbage data to file to provoke ENOSPC and other
 
432
                 * errors.
 
433
                 */
 
434
                (void) fprintf (auth_file, "%s", dummy_auth);
 
435
                (void) fflush (auth_file);
 
436
                if (ferror (auth_file))
 
437
                {
 
438
                    err = errno;
 
439
                    ret = FALSE;
 
440
                }
 
441
                /*
 
442
                 * Rewind so that the garbage data is overwritten later.
 
443
                 */
 
444
                rewind(auth_file);
 
445
        }
395
446
        for (i = 0; i < count; i++)
396
447
        {
397
448
            /*
400
451
             * to the auth file so xrdb and setup programs don't fail.
401
452
             */
402
453
            if (auths[i]->data_length > 0)
403
 
                if (!XauWriteAuth (auth_file, auths[i]) ||
404
 
                    fflush (auth_file) == EOF)
405
 
                {
406
 
                    LogError ("Cannot write server authorization file %s\n",
407
 
                              d->authFile);
 
454
                if (!XauWriteAuth (auth_file, auths[i]))
 
455
                {
 
456
                    Debug ("XauWriteAuth() failed\n");
 
457
                }
 
458
                (void) fflush (auth_file);
 
459
                if (ferror (auth_file))
 
460
                {
 
461
                    err = errno;
408
462
                    ret = FALSE;
409
 
                    free (d->authFile);
410
 
                    d->authFile = NULL;
411
463
                }
412
464
        }
 
465
        /*
 
466
         * XXX: This is not elegant, but stdio has no truncation function.
 
467
         */
 
468
        if (ftruncate(fileno(auth_file), ftell(auth_file)))
 
469
        {
 
470
                Debug ("ftruncate() failed\n");
 
471
        }
413
472
        fclose (auth_file);
 
473
 
 
474
    }
 
475
    if (ret == FALSE)
 
476
    {
 
477
        LogError ("Cannot write to server authorization file %s%s%s\n",
 
478
                  d->authFile,
 
479
                  err ? ": " : "",
 
480
                  err ? _SysErrorMsg (errno) : "");
 
481
        free (d->authFile);
 
482
        d->authFile = NULL;
414
483
    }
415
484
    return ret;
416
485
}
496
565
openFiles (char *name, char *new_name, FILE **oldp, FILE **newp)
497
566
{
498
567
        mode_t  mask;
 
568
        int newfd;
499
569
 
500
570
        strcpy (new_name, name);
501
571
        strcat (new_name, "-n");
 
572
        /*
 
573
         * Set safe umask for file creation operations.
 
574
         */
502
575
        mask = umask (0077);
 
576
        /*
 
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.
 
579
         */
503
580
        (void) unlink (new_name);
504
 
        *newp = fopen (new_name, "w");
 
581
        newfd = open (new_name, O_WRONLY | O_CREAT | O_EXCL, 0600);
 
582
        if (newfd >= 0)
 
583
            *newp = fdopen (newfd, "w");
 
584
        else
 
585
        {
 
586
            LogError ("Cannot create file %s: %s\n", new_name,
 
587
                      _SysErrorMsg (errno));
 
588
            *newp = NULL;
 
589
        }
 
590
        /*
 
591
         * There are no more attempts to create files after this point;
 
592
         * restore the original umask.
 
593
         */
505
594
        (void) umask (mask);
506
595
        if (!*newp) {
507
596
                Debug ("can't open new file %s\n", new_name);