PostgreSQL Source Code: contrib/sepgsql/label.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

12

13#include <selinux/label.h>

14

32#include "utils/fmgroids.h"

37

38

39

40

44

45

46

47

48

49

50

51

52

53

54

55

56

57

60

62

64

65typedef struct

66{

70

71

72

73

74

75

76

77

78char *

80{

81

84

85

87 {

89

90 if (plabel->label)

91 return plabel->label;

92 }

95

96

99}

100

101

102

103

104

105

106

107

108

109static void

111{

112 const char *tcontext;

115

116

117 if (!new_label)

119 else

120 {

121 if (security_check_context_raw(new_label) < 0)

123 (errcode(ERRCODE_INVALID_NAME),

124 errmsg("SELinux: invalid security label: \"%s\"",

125 new_label)));

126 tcontext = new_label;

127 }

128

129

133 NULL,

134 true);

135

139 NULL,

140 true);

141

142

143

144

145

147

150 if (new_label)

153

155}

156

157

158

159

160

161

162

163static void

165{

167 {

169 {

171 char *new_label;

172

173 if (plabel->label)

176 else

177 new_label = NULL;

178

181

183

184

185

186

187

188

190 }

191 }

194}

195

196

197

198

199

200

201

202static void

205{

207

209 {

211 {

213

214 if (plabel->subid == mySubid)

217 }

218 }

219}

220

221

222

223

224

225

226

227

228static void

230{

232 (*next_client_auth_hook) (port, status);

233

234

235

236

237

239 return;

240

241

242

243

246 (errcode(ERRCODE_INTERNAL_ERROR),

247 errmsg("SELinux: unable to get peer label: %m")));

248

249

250

251

252

255 else

257}

258

259

260

261

262

263

264

265

266static bool

268{

270

273 return true;

274

275

276

277

278

279

280

282 return true;

283

284

285

286

287

288

289

290 object.classId = ProcedureRelationId;

291 object.objectId = functionId;

292 object.objectSubId = 0;

298 return true;

299

300 return false;

301}

302

303

304

305

306

307

308

309static void

312{

313 struct

314 {

315 char *old_label;

316 char *new_label;

317 Datum next_private;

318 } *stack;

319

320 switch (event)

321 {

324 if (!stack)

325 {

327

329 stack = palloc(sizeof(*stack));

330 stack->old_label = NULL;

332 stack->next_private = 0;

333

335

336

337

338

339

340

341

342

343

344

345

346 if (stack->new_label)

347 {

349

350 object.classId = ProcedureRelationId;

351 object.objectId = flinfo->fn_oid;

352 object.objectSubId = 0;

357 true);

358

362 NULL, true);

363 }

365 }

366 Assert(!stack->old_label);

367 if (stack->new_label)

368 {

371 }

373 (*next_fmgr_hook) (event, flinfo, &stack->next_private);

374 break;

375

379

381 (*next_fmgr_hook) (event, flinfo, &stack->next_private);

382

383 if (stack->new_label)

384 {

386 stack->old_label = NULL;

387 }

388 break;

389

390 default:

391 elog(ERROR, "unexpected event type: %d", (int) event);

392 break;

393 }

394}

395

396

397

398

399

400

401

402void

404{

405

406

407

408

409

410

411

412

413

414

417 (errcode(ERRCODE_INTERNAL_ERROR),

418 errmsg("SELinux: failed to get server security label: %m")));

419

420

423

424

427

430

431

434}

435

436

437

438

439

440

441

442

443char *

445{

448

449 object.classId = classId;

450 object.objectId = objectId;

451 object.objectSubId = subId;

452

454 if (label || security_check_context_raw(label))

455 {

456 char *unlabeled;

457

458 if (security_get_initial_context_raw("unlabeled", &unlabeled) < 0)

460 (errcode(ERRCODE_INTERNAL_ERROR),

461 errmsg("SELinux: failed to get initial security label: %m")));

463 {

465 }

467 {

468 freecon(unlabeled);

469 }

471 }

473}

474

475

476

477

478

479

480void

482{

483

484

485

486

487 if (seclabel &&

488 security_check_context_raw(seclabel) < 0)

490 (errcode(ERRCODE_INVALID_NAME),

491 errmsg("SELinux: invalid security label: \"%s\"", seclabel)));

492

493

494

495

497 {

498 case DatabaseRelationId:

500 break;

501

502 case NamespaceRelationId:

504 break;

505

506 case RelationRelationId:

509 seclabel);

510 else

513 seclabel);

514 break;

515

516 case ProcedureRelationId:

518 break;

519

520 default:

522 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

523 errmsg("sepgsql provider does not support labels on %s",

525 break;

526 }

527}

528

529

530

531

532

533

537{

538 char *client_label;

539

542

544

546}

547

548

549

550

551

552

556{

557 const char *new_label;

558

560 new_label = NULL;

561 else

563

565

567}

568

569

570

571

572

573

574

578{

580 char *raw_label;

581 char *result;

582

585 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

586 errmsg("sepgsql is not enabled")));

587

589 &raw_label) < 0)

591 (errcode(ERRCODE_INTERNAL_ERROR),

592 errmsg("SELinux: could not translate security label: %m")));

593

595 {

596 result = pstrdup(raw_label);

597 }

599 {

600 freecon(raw_label);

601 }

603

605}

606

607

608

609

610

611

612

616{

618 char *qual_label;

619 char *result;

620

623 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

624 errmsg("sepgsql is not currently enabled")));

625

627 &qual_label) < 0)

629 (errcode(ERRCODE_INTERNAL_ERROR),

630 errmsg("SELinux: could not translate security label: %m")));

631

633 {

634 result = pstrdup(qual_label);

635 }

637 {

638 freecon(qual_label);

639 }

641

643}

644

645

646

647

648

649

650

651static char *

653 const char *src3, const char *src4)

654{

656

658 if (src1)

660 if (src2)

662 if (src3)

664 if (src4)

666 return result.data;

667}

668

669

670

671

672

673

674

675

676static void

678{

683 char *namespace_name;

684 Oid namespace_id;

685 char *relation_name;

686

687

688

689

690

692

694 NULL, 0, NULL);

696 {

702 char *objname;

703 int objtype = 1234;

705 char *context;

706

707

708

709

710

711 switch (catalogId)

712 {

713 case DatabaseRelationId:

715

716 objtype = SELABEL_DB_DATABASE;

717

719 NULL, NULL, NULL);

720

721 object.classId = DatabaseRelationId;

722 object.objectId = datForm->oid;

723 object.objectSubId = 0;

724 break;

725

726 case NamespaceRelationId:

728

729 objtype = SELABEL_DB_SCHEMA;

730

732 NameStr(nspForm->nspname),

733 NULL, NULL);

734

735 object.classId = NamespaceRelationId;

736 object.objectId = nspForm->oid;

737 object.objectSubId = 0;

738 break;

739

740 case RelationRelationId:

742

743 if (relForm->relkind == RELKIND_RELATION ||

744 relForm->relkind == RELKIND_PARTITIONED_TABLE)

745 objtype = SELABEL_DB_TABLE;

746 else if (relForm->relkind == RELKIND_SEQUENCE)

747 objtype = SELABEL_DB_SEQUENCE;

748 else if (relForm->relkind == RELKIND_VIEW)

749 objtype = SELABEL_DB_VIEW;

750 else

751 continue;

752

755 namespace_name,

756 NameStr(relForm->relname),

757 NULL);

758 pfree(namespace_name);

759

760 object.classId = RelationRelationId;

761 object.objectId = relForm->oid;

762 object.objectSubId = 0;

763 break;

764

765 case AttributeRelationId:

767

768 if (get_rel_relkind(attForm->attrelid) != RELKIND_RELATION &&

769 get_rel_relkind(attForm->attrelid) != RELKIND_PARTITIONED_TABLE)

770 continue;

771

772 objtype = SELABEL_DB_COLUMN;

773

776 relation_name = get_rel_name(attForm->attrelid);

778 namespace_name,

779 relation_name,

780 NameStr(attForm->attname));

781 pfree(namespace_name);

782 pfree(relation_name);

783

784 object.classId = RelationRelationId;

785 object.objectId = attForm->attrelid;

786 object.objectSubId = attForm->attnum;

787 break;

788

789 case ProcedureRelationId:

791

792 objtype = SELABEL_DB_PROCEDURE;

793

796 namespace_name,

797 NameStr(proForm->proname),

798 NULL);

799 pfree(namespace_name);

800

801 object.classId = ProcedureRelationId;

802 object.objectId = proForm->oid;

803 object.objectSubId = 0;

804 break;

805

806 default:

807 elog(ERROR, "unexpected catalog id: %u", catalogId);

808 objname = NULL;

809 break;

810 }

811

812 if (selabel_lookup_raw(sehnd, &context, objname, objtype) == 0)

813 {

815 {

816

817

818

819

821

823 }

825 {

826 freecon(context);

827 }

829 }

830 else if (errno == ENOENT)

832 (errmsg("SELinux: no initial label assigned for %s (type=%d), skipping",

833 objname, objtype)));

834 else

836 (errcode(ERRCODE_INTERNAL_ERROR),

837 errmsg("SELinux: could not determine initial security label for %s (type=%d): %m", objname, objtype)));

838

840 }

842

844}

845

846

847

848

849

850

851

852

853

854

855

856

860{

861 struct selabel_handle *sehnd;

862 struct selinux_opt seopts;

863

864

865

866

869 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

870 errmsg("sepgsql is not currently enabled")));

871

872

873

874

875

878 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

879 errmsg("SELinux: must be superuser to restore initial contexts")));

880

881

882

883

884

886 {

887 seopts.type = SELABEL_OPT_UNUSED;

888 seopts.value = NULL;

889 }

890 else

891 {

892 seopts.type = SELABEL_OPT_PATH;

894 }

895 sehnd = selabel_open(SELABEL_CTX_DB, &seopts, 1);

896 if (!sehnd)

898 (errcode(ERRCODE_INTERNAL_ERROR),

899 errmsg("SELinux: failed to initialize labeling handle: %m")));

901 {

907 }

909 {

910 selabel_close(sehnd);

911 }

913

915}

ClientAuthentication_hook_type ClientAuthentication_hook

void(* ClientAuthentication_hook_type)(Port *, int)

#define TextDatumGetCString(d)

void sepgsql_proc_relabel(Oid functionId, const char *seclabel)

void sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum, const char *seclabel)

void sepgsql_relation_relabel(Oid relOid, const char *seclabel)

void sepgsql_database_relabel(Oid databaseId, const char *seclabel)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

#define palloc0_object(type)

PGDLLIMPORT needs_fmgr_hook_type needs_fmgr_hook

PGDLLIMPORT fmgr_hook_type fmgr_hook

#define PG_GETARG_TEXT_PP(n)

bool(* needs_fmgr_hook_type)(Oid fn_oid)

#define PG_GETARG_DATUM(n)

#define PG_RETURN_TEXT_P(x)

void(* fmgr_hook_type)(FmgrHookEventType event, FmgrInfo *flinfo, Datum *arg)

#define PG_RETURN_BOOL(x)

void systable_endscan(SysScanDesc sysscan)

HeapTuple systable_getnext(SysScanDesc sysscan)

SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)

Assert(PointerIsAligned(start, uint64))

bool sepgsql_get_permissive(void)

#define HeapTupleIsValid(tuple)

static void * GETSTRUCT(const HeapTupleData *tuple)

Datum sepgsql_getcon(PG_FUNCTION_ARGS)

static fmgr_hook_type next_fmgr_hook

static void sepgsql_fmgr_hook(FmgrHookEventType event, FmgrInfo *flinfo, Datum *private)

void sepgsql_init_client_label(void)

static char * client_label_committed

static needs_fmgr_hook_type next_needs_fmgr_hook

static char * quote_object_name(const char *src1, const char *src2, const char *src3, const char *src4)

Datum sepgsql_mcstrans_out(PG_FUNCTION_ARGS)

static void exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)

PG_FUNCTION_INFO_V1(sepgsql_getcon)

static char * client_label_peer

static List * client_label_pending

char * sepgsql_get_label(Oid classId, Oid objectId, int32 subId)

void sepgsql_object_relabel(const ObjectAddress *object, const char *seclabel)

Datum sepgsql_restorecon(PG_FUNCTION_ARGS)

static void sepgsql_subxact_callback(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid, void *arg)

static void sepgsql_client_auth(Port *port, int status)

static char * client_label_func

char * sepgsql_get_client_label(void)

static void sepgsql_xact_callback(XactEvent event, void *arg)

Datum sepgsql_setcon(PG_FUNCTION_ARGS)

static ClientAuthentication_hook_type next_client_auth_hook

Datum sepgsql_mcstrans_in(PG_FUNCTION_ARGS)

static void sepgsql_set_client_label(const char *new_label)

static bool sepgsql_needs_fmgr_hook(Oid functionId)

List * lappend(List *list, void *datum)

char * get_rel_name(Oid relid)

char * get_database_name(Oid dbid)

char get_rel_relkind(Oid relid)

Oid get_rel_namespace(Oid relid)

char * get_namespace_name(Oid nspid)

char * MemoryContextStrdup(MemoryContext context, const char *string)

char * pstrdup(const char *in)

void pfree(void *pointer)

MemoryContext TopMemoryContext

MemoryContext CurTransactionContext

char * getObjectTypeDescription(const ObjectAddress *object, bool missing_ok)

char * getObjectDescription(const ObjectAddress *object, bool missing_ok)

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

FormData_pg_attribute * Form_pg_attribute

FormData_pg_class * Form_pg_class

FormData_pg_database * Form_pg_database

#define foreach_delete_current(lst, var_or_cell)

FormData_pg_namespace * Form_pg_namespace

FormData_pg_proc * Form_pg_proc

static Datum PointerGetDatum(const void *X)

static Pointer DatumGetPointer(Datum X)

const char * quote_identifier(const char *ident)

void sepgsql_schema_relabel(Oid namespaceId, const char *seclabel)

void SetSecurityLabel(const ObjectAddress *object, const char *provider, const char *label)

char * GetSecurityLabel(const ObjectAddress *object, const char *provider)

int sepgsql_set_mode(int new_mode)

bool sepgsql_is_enabled(void)

char * sepgsql_avc_trusted_proc(Oid functionId)

bool sepgsql_avc_check_perms_label(const char *tcontext, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)

#define SEPG_DB_PROCEDURE__EXECUTE

#define SEPG_PROCESS__SETCURRENT

#define SEPG_PROCESS__TRANSITION

#define SEPG_PROCESS__DYNTRANSITION

#define SEPG_DB_PROCEDURE__ENTRYPOINT

#define SEPG_CLASS_DB_PROCEDURE

#define SEPGSQL_AVC_NOAUDIT

#define SEPGSQL_LABEL_TAG

#define SEPGSQL_MODE_DEFAULT

#define SEPG_CLASS_PROCESS

#define SEPGSQL_MODE_PERMISSIVE

bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)

void appendStringInfo(StringInfo str, const char *fmt,...)

void appendStringInfoString(StringInfo str, const char *s)

void initStringInfo(StringInfo str)

void table_close(Relation relation, LOCKMODE lockmode)

Relation table_open(Oid relationId, LOCKMODE lockmode)

text * cstring_to_text(const char *s)

char * text_to_cstring(const text *t)

SubTransactionId GetCurrentSubTransactionId(void)

void RegisterXactCallback(XactCallback callback, void *arg)

void RegisterSubXactCallback(SubXactCallback callback, void *arg)

@ SUBXACT_EVENT_ABORT_SUB