22
22
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
23
23
* Portions Copyright (c) 1994, Regents of the University of California
24
24
*
25
- * $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.1 2005/02/20 02:22:00 tgl Exp $
25
+ * $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.2 2005/02/20 04:45:59 tgl Exp $
26
26
*
27
27
*-------------------------------------------------------------------------
28
28
*/
@@ -278,7 +278,7 @@ write_database_file(Relation drel)
278
278
}
279
279
280
280
/*
281
- * File format is: "dbname" oid frozenxid
281
+ * The file format is: "dbname" oid frozenxid
282
282
*
283
283
* The xid is not needed for backend startup, but may be of use
284
284
* for forensic purposes.
@@ -317,13 +317,6 @@ write_database_file(Relation drel)
317
317
318
318
/*
319
319
* write_group_file: update the flat group file
320
- *
321
- * XXX this will never be able to work during system bootstrap: we don't
322
- * have either TOAST support or SysCache support. Need to redefine both
323
- * the catalog and file contents to fix this completely. In the short term
324
- * we can handle everything except an out-of-line-toasted grolist, if we
325
- * change the flat file definition to store numeric sysids instead of
326
- * user names.
327
320
*/
328
321
static void
329
322
write_group_file (Relation grel )
@@ -335,7 +328,6 @@ write_group_file(Relation grel)
335
328
mode_t oumask ;
336
329
HeapScanDesc scan ;
337
330
HeapTuple tuple ;
338
- TupleDesc dsc = RelationGetDescr (grel );
339
331
340
332
/*
341
333
* Create a temporary filename to be renamed later. This prevents the
@@ -364,22 +356,19 @@ write_group_file(Relation grel)
364
356
scan = heap_beginscan (grel , SnapshotSelf , 0 , NULL );
365
357
while ((tuple = heap_getnext (scan , ForwardScanDirection )) != NULL )
366
358
{
367
- Datum datum ,
368
- grolist_datum ;
369
- bool isnull ;
359
+ Form_pg_group grpform = (Form_pg_group ) GETSTRUCT (tuple );
360
+ HeapTupleHeader tup = tuple -> t_data ;
361
+ char * tp ; /* ptr to tuple data */
362
+ long off ; /* offset in tuple data */
363
+ bits8 * bp = tup -> t_bits ; /* ptr to null bitmask in tuple */
364
+ Datum datum ;
370
365
char * groname ;
371
366
IdList * grolist_p ;
372
367
AclId * aidp ;
373
368
int i ,
374
369
num ;
375
- char * usename ;
376
- bool first_user = true;
377
370
378
- datum = heap_getattr (tuple , Anum_pg_group_groname , dsc , & isnull );
379
- /* ignore NULL groupnames --- shouldn't happen */
380
- if (isnull )
381
- continue ;
382
- groname = NameStr (* DatumGetName (datum ));
371
+ groname = NameStr (grpform -> groname );
383
372
384
373
/*
385
374
* Check for illegal characters in the group name.
@@ -391,57 +380,58 @@ write_group_file(Relation grel)
391
380
continue ;
392
381
}
393
382
394
- grolist_datum = heap_getattr (tuple , Anum_pg_group_grolist , dsc , & isnull );
395
- /* Ignore NULL group lists */
396
- if (isnull )
383
+ /*
384
+ * We can't use heap_getattr() here because during startup we will
385
+ * not have any tupdesc for pg_group. Fortunately it's not too
386
+ * hard to work around this. grolist is the first possibly-null
387
+ * field so we can compute its offset directly.
388
+ */
389
+ tp = (char * ) tup + tup -> t_hoff ;
390
+ off = offsetof(FormData_pg_group , grolist );
391
+
392
+ if (HeapTupleHasNulls (tuple ) &&
393
+ att_isnull (Anum_pg_group_grolist - 1 , bp ))
394
+ {
395
+ /* grolist is null, so we can ignore this group */
396
+ continue ;
397
+ }
398
+
399
+ /* assume grolist is pass-by-ref */
400
+ datum = PointerGetDatum (tp + off );
401
+
402
+ /*
403
+ * We can't currently support out-of-line toasted group lists in
404
+ * startup mode (the tuptoaster won't work). This sucks, but it
405
+ * should be something of a corner case. Live with it until we
406
+ * can redesign pg_group.
407
+ *
408
+ * Detect startup mode by noting whether we got a tupdesc.
409
+ */
410
+ if (VARATT_IS_EXTERNAL (DatumGetPointer (datum )) &&
411
+ RelationGetDescr (grel ) == NULL )
397
412
continue ;
398
413
399
414
/* be sure the IdList is not toasted */
400
- grolist_p = DatumGetIdListP (grolist_datum );
415
+ grolist_p = DatumGetIdListP (datum );
401
416
402
- /* scan grolist */
403
- num = IDLIST_NUM (grolist_p );
417
+ /*
418
+ * The file format is: "groupname" usesysid1 usesysid2 ...
419
+ *
420
+ * We ignore groups that have no members.
421
+ */
404
422
aidp = IDLIST_DAT (grolist_p );
405
- for (i = 0 ; i < num ; ++ i )
423
+ num = IDLIST_NUM (grolist_p );
424
+ if (num > 0 )
406
425
{
407
- tuple = SearchSysCache (SHADOWSYSID ,
408
- PointerGetDatum (aidp [i ]),
409
- 0 , 0 , 0 );
410
- if (HeapTupleIsValid (tuple ))
411
- {
412
- usename = NameStr (((Form_pg_shadow ) GETSTRUCT (tuple ))-> usename );
413
-
414
- /*
415
- * Check for illegal characters in the user name.
416
- */
417
- if (!name_okay (usename ))
418
- {
419
- ereport (LOG ,
420
- (errmsg ("invalid user name \"%s\"" , usename )));
421
- continue ;
422
- }
423
-
424
- /*
425
- * File format is: "groupname" "user1" "user2" "user3"
426
- */
427
- if (first_user )
428
- {
429
- fputs_quote (groname , fp );
430
- fputs ("\t" , fp );
431
- first_user = false;
432
- }
433
- else
434
- fputs (" " , fp );
435
-
436
- fputs_quote (usename , fp );
437
-
438
- ReleaseSysCache (tuple );
439
- }
440
- }
441
- if (!first_user )
426
+ fputs_quote (groname , fp );
427
+ fprintf (fp , "\t%u" , aidp [0 ]);
428
+ for (i = 1 ; i < num ; ++ i )
429
+ fprintf (fp , " %u" , aidp [i ]);
442
430
fputs ("\n" , fp );
431
+ }
432
+
443
433
/* if IdList was toasted, free detoasted copy */
444
- if ((Pointer ) grolist_p != DatumGetPointer (grolist_datum ))
434
+ if ((Pointer ) grolist_p != DatumGetPointer (datum ))
445
435
pfree (grolist_p );
446
436
}
447
437
heap_endscan (scan );
@@ -517,8 +507,10 @@ write_user_file(Relation urel)
517
507
char * usename ,
518
508
* passwd ,
519
509
* valuntil ;
510
+ AclId usesysid ;
520
511
521
512
usename = NameStr (pwform -> usename );
513
+ usesysid = pwform -> usesysid ;
522
514
523
515
/*
524
516
* We can't use heap_getattr() here because during startup we will
@@ -532,30 +524,26 @@ write_user_file(Relation urel)
532
524
if (HeapTupleHasNulls (tuple ) &&
533
525
att_isnull (Anum_pg_shadow_passwd - 1 , bp ))
534
526
{
535
- /*
536
- * It can be argued that people having a null password shouldn't
537
- * be allowed to connect under password authentication, because
538
- * they need to have a password set up first. If you think
539
- * assuming an empty password in that case is better, change this
540
- * logic to look something like the code for valuntil.
541
- */
542
- continue ;
527
+ /* passwd is null, emit as an empty string */
528
+ passwd = pstrdup ("" );
543
529
}
530
+ else
531
+ {
532
+ /* assume passwd is pass-by-ref */
533
+ datum = PointerGetDatum (tp + off );
544
534
545
- /* assume passwd is pass-by-ref */
546
- datum = PointerGetDatum (tp + off );
547
-
548
- /*
549
- * The password probably shouldn't ever be out-of-line toasted;
550
- * if it is, ignore it, since we can't handle that in startup mode.
551
- */
552
- if (VARATT_IS_EXTERNAL (DatumGetPointer (datum )))
553
- continue ;
554
-
555
- passwd = DatumGetCString (DirectFunctionCall1 (textout , datum ));
535
+ /*
536
+ * The password probably shouldn't ever be out-of-line toasted;
537
+ * if it is, ignore it, since we can't handle that in startup mode.
538
+ */
539
+ if (VARATT_IS_EXTERNAL (DatumGetPointer (datum )))
540
+ passwd = pstrdup ("" );
541
+ else
542
+ passwd = DatumGetCString (DirectFunctionCall1 (textout , datum ));
556
543
557
- /* assume passwd has attlen -1 */
558
- off = att_addlength (off , -1 , tp + off );
544
+ /* assume passwd has attlen -1 */
545
+ off = att_addlength (off , -1 , tp + off );
546
+ }
559
547
560
548
if (HeapTupleHasNulls (tuple ) &&
561
549
att_isnull (Anum_pg_shadow_valuntil - 1 , bp ))
@@ -588,8 +576,11 @@ write_user_file(Relation urel)
588
576
continue ;
589
577
}
590
578
579
+ /*
580
+ * The file format is: "usename" usesysid "passwd" "valuntil"
581
+ */
591
582
fputs_quote (usename , fp );
592
- fputs ( " " , fp );
583
+ fprintf ( fp , " %u " , usesysid );
593
584
fputs_quote (passwd , fp );
594
585
fputs (" " , fp );
595
586
fputs_quote (valuntil , fp );
@@ -664,17 +655,13 @@ BuildFlatFiles(bool database_only)
664
655
665
656
if (!database_only )
666
657
{
667
- #ifdef NOT_YET
668
- /* XXX doesn't work yet for reasons stated above */
669
-
670
658
/* hard-wired path to pg_group */
671
659
rnode .spcNode = GLOBALTABLESPACE_OID ;
672
660
rnode .dbNode = 0 ;
673
661
rnode .relNode = RelOid_pg_group ;
674
662
675
663
rel = XLogOpenRelation (true, 0 , rnode );
676
664
write_group_file (rel );
677
- #endif
678
665
679
666
/* hard-wired path to pg_shadow */
680
667
rnode .spcNode = GLOBALTABLESPACE_OID ;
0 commit comments