PostgreSQL Source Code  git master
hbafuncs.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * hbafuncs.c
4  * Support functions for SQL views of authentication files.
5  *
6  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/backend/utils/adt/hbafuncs.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16 
17 #include "catalog/objectaddress.h"
18 #include "common/ip.h"
19 #include "funcapi.h"
20 #include "libpq/hba.h"
21 #include "utils/array.h"
22 #include "utils/builtins.h"
23 #include "utils/guc.h"
24 
25 
26 static ArrayType *get_hba_options(HbaLine *hba);
27 static void fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
28  int rule_number, char *filename, int lineno,
29  HbaLine *hba, const char *err_msg);
30 static void fill_hba_view(Tuplestorestate *tuple_store, TupleDesc tupdesc);
31 static void fill_ident_line(Tuplestorestate *tuple_store, TupleDesc tupdesc,
32  int map_number, char *filename, int lineno,
33  IdentLine *ident, const char *err_msg);
34 static void fill_ident_view(Tuplestorestate *tuple_store, TupleDesc tupdesc);
35 
36 
37 /*
38  * This macro specifies the maximum number of authentication options
39  * that are possible with any given authentication method that is supported.
40  * Currently LDAP supports 11, and there are 3 that are not dependent on
41  * the auth method here. It may not actually be possible to set all of them
42  * at the same time, but we'll set the macro value high enough to be
43  * conservative and avoid warnings from static analysis tools.
44  */
45 #define MAX_HBA_OPTIONS 14
46 
47 /*
48  * Create a text array listing the options specified in the HBA line.
49  * Return NULL if no options are specified.
50  */
51 static ArrayType *
53 {
54  int noptions;
56 
57  noptions = 0;
58 
59  if (hba->auth_method == uaGSS || hba->auth_method == uaSSPI)
60  {
61  if (hba->include_realm)
62  options[noptions++] =
63  CStringGetTextDatum("include_realm=true");
64 
65  if (hba->krb_realm)
66  options[noptions++] =
67  CStringGetTextDatum(psprintf("krb_realm=%s", hba->krb_realm));
68  }
69 
70  if (hba->usermap)
71  options[noptions++] =
72  CStringGetTextDatum(psprintf("map=%s", hba->usermap));
73 
74  if (hba->clientcert != clientCertOff)
75  options[noptions++] =
76  CStringGetTextDatum(psprintf("clientcert=%s", (hba->clientcert == clientCertCA) ? "verify-ca" : "verify-full"));
77 
78  if (hba->pamservice)
79  options[noptions++] =
80  CStringGetTextDatum(psprintf("pamservice=%s", hba->pamservice));
81 
82  if (hba->auth_method == uaLDAP)
83  {
84  if (hba->ldapserver)
85  options[noptions++] =
86  CStringGetTextDatum(psprintf("ldapserver=%s", hba->ldapserver));
87 
88  if (hba->ldapport)
89  options[noptions++] =
90  CStringGetTextDatum(psprintf("ldapport=%d", hba->ldapport));
91 
92  if (hba->ldaptls)
93  options[noptions++] =
94  CStringGetTextDatum("ldaptls=true");
95 
96  if (hba->ldapprefix)
97  options[noptions++] =
98  CStringGetTextDatum(psprintf("ldapprefix=%s", hba->ldapprefix));
99 
100  if (hba->ldapsuffix)
101  options[noptions++] =
102  CStringGetTextDatum(psprintf("ldapsuffix=%s", hba->ldapsuffix));
103 
104  if (hba->ldapbasedn)
105  options[noptions++] =
106  CStringGetTextDatum(psprintf("ldapbasedn=%s", hba->ldapbasedn));
107 
108  if (hba->ldapbinddn)
109  options[noptions++] =
110  CStringGetTextDatum(psprintf("ldapbinddn=%s", hba->ldapbinddn));
111 
112  if (hba->ldapbindpasswd)
113  options[noptions++] =
114  CStringGetTextDatum(psprintf("ldapbindpasswd=%s",
115  hba->ldapbindpasswd));
116 
117  if (hba->ldapsearchattribute)
118  options[noptions++] =
119  CStringGetTextDatum(psprintf("ldapsearchattribute=%s",
120  hba->ldapsearchattribute));
121 
122  if (hba->ldapsearchfilter)
123  options[noptions++] =
124  CStringGetTextDatum(psprintf("ldapsearchfilter=%s",
125  hba->ldapsearchfilter));
126 
127  if (hba->ldapscope)
128  options[noptions++] =
129  CStringGetTextDatum(psprintf("ldapscope=%d", hba->ldapscope));
130  }
131 
132  if (hba->auth_method == uaRADIUS)
133  {
134  if (hba->radiusservers_s)
135  options[noptions++] =
136  CStringGetTextDatum(psprintf("radiusservers=%s", hba->radiusservers_s));
137 
138  if (hba->radiussecrets_s)
139  options[noptions++] =
140  CStringGetTextDatum(psprintf("radiussecrets=%s", hba->radiussecrets_s));
141 
142  if (hba->radiusidentifiers_s)
143  options[noptions++] =
144  CStringGetTextDatum(psprintf("radiusidentifiers=%s", hba->radiusidentifiers_s));
145 
146  if (hba->radiusports_s)
147  options[noptions++] =
148  CStringGetTextDatum(psprintf("radiusports=%s", hba->radiusports_s));
149  }
150 
151  /* If you add more options, consider increasing MAX_HBA_OPTIONS. */
153 
154  if (noptions > 0)
155  return construct_array_builtin(options, noptions, TEXTOID);
156  else
157  return NULL;
158 }
159 
160 /* Number of columns in pg_hba_file_rules view */
161 #define NUM_PG_HBA_FILE_RULES_ATTS 11
162 
163 /*
164  * fill_hba_line
165  * Build one row of pg_hba_file_rules view, add it to tuplestore.
166  *
167  * tuple_store: where to store data
168  * tupdesc: tuple descriptor for the view
169  * rule_number: unique identifier among all valid rules
170  * filename: configuration file name (must always be valid)
171  * lineno: line number of configuration file (must always be valid)
172  * hba: parsed line data (can be NULL, in which case err_msg should be set)
173  * err_msg: error message (NULL if none)
174  *
175  * Note: leaks memory, but we don't care since this is run in a short-lived
176  * memory context.
177  */
178 static void
180  int rule_number, char *filename, int lineno, HbaLine *hba,
181  const char *err_msg)
182 {
184  bool nulls[NUM_PG_HBA_FILE_RULES_ATTS];
185  char buffer[NI_MAXHOST];
186  HeapTuple tuple;
187  int index;
188  ListCell *lc;
189  const char *typestr;
190  const char *addrstr;
191  const char *maskstr;
193 
195 
196  memset(values, 0, sizeof(values));
197  memset(nulls, 0, sizeof(nulls));
198  index = 0;
199 
200  /* rule_number, nothing on error */
201  if (err_msg)
202  nulls[index++] = true;
203  else
204  values[index++] = Int32GetDatum(rule_number);
205 
206  /* file_name */
208 
209  /* line_number */
210  values[index++] = Int32GetDatum(lineno);
211 
212  if (hba != NULL)
213  {
214  /* type */
215  /* Avoid a default: case so compiler will warn about missing cases */
216  typestr = NULL;
217  switch (hba->conntype)
218  {
219  case ctLocal:
220  typestr = "local";
221  break;
222  case ctHost:
223  typestr = "host";
224  break;
225  case ctHostSSL:
226  typestr = "hostssl";
227  break;
228  case ctHostNoSSL:
229  typestr = "hostnossl";
230  break;
231  case ctHostGSS:
232  typestr = "hostgssenc";
233  break;
234  case ctHostNoGSS:
235  typestr = "hostnogssenc";
236  break;
237  }
238  if (typestr)
239  values[index++] = CStringGetTextDatum(typestr);
240  else
241  nulls[index++] = true;
242 
243  /* database */
244  if (hba->databases)
245  {
246  /*
247  * Flatten AuthToken list to string list. It might seem that we
248  * should re-quote any quoted tokens, but that has been rejected
249  * on the grounds that it makes it harder to compare the array
250  * elements to other system catalogs. That makes entries like
251  * "all" or "samerole" formally ambiguous ... but users who name
252  * databases/roles that way are inflicting their own pain.
253  */
254  List *names = NIL;
255 
256  foreach(lc, hba->databases)
257  {
258  AuthToken *tok = lfirst(lc);
259 
260  names = lappend(names, tok->string);
261  }
263  }
264  else
265  nulls[index++] = true;
266 
267  /* user */
268  if (hba->roles)
269  {
270  /* Flatten AuthToken list to string list; see comment above */
271  List *roles = NIL;
272 
273  foreach(lc, hba->roles)
274  {
275  AuthToken *tok = lfirst(lc);
276 
277  roles = lappend(roles, tok->string);
278  }
280  }
281  else
282  nulls[index++] = true;
283 
284  /* address and netmask */
285  /* Avoid a default: case so compiler will warn about missing cases */
286  addrstr = maskstr = NULL;
287  switch (hba->ip_cmp_method)
288  {
289  case ipCmpMask:
290  if (hba->hostname)
291  {
292  addrstr = hba->hostname;
293  }
294  else
295  {
296  /*
297  * Note: if pg_getnameinfo_all fails, it'll set buffer to
298  * "???", which we want to return.
299  */
300  if (hba->addrlen > 0)
301  {
302  if (pg_getnameinfo_all(&hba->addr, hba->addrlen,
303  buffer, sizeof(buffer),
304  NULL, 0,
305  NI_NUMERICHOST) == 0)
306  clean_ipv6_addr(hba->addr.ss_family, buffer);
307  addrstr = pstrdup(buffer);
308  }
309  if (hba->masklen > 0)
310  {
311  if (pg_getnameinfo_all(&hba->mask, hba->masklen,
312  buffer, sizeof(buffer),
313  NULL, 0,
314  NI_NUMERICHOST) == 0)
315  clean_ipv6_addr(hba->mask.ss_family, buffer);
316  maskstr = pstrdup(buffer);
317  }
318  }
319  break;
320  case ipCmpAll:
321  addrstr = "all";
322  break;
323  case ipCmpSameHost:
324  addrstr = "samehost";
325  break;
326  case ipCmpSameNet:
327  addrstr = "samenet";
328  break;
329  }
330  if (addrstr)
331  values[index++] = CStringGetTextDatum(addrstr);
332  else
333  nulls[index++] = true;
334  if (maskstr)
335  values[index++] = CStringGetTextDatum(maskstr);
336  else
337  nulls[index++] = true;
338 
339  /* auth_method */
341 
342  /* options */
343  options = get_hba_options(hba);
344  if (options)
346  else
347  nulls[index++] = true;
348  }
349  else
350  {
351  /* no parsing result, so set relevant fields to nulls */
352  memset(&nulls[3], true, (NUM_PG_HBA_FILE_RULES_ATTS - 4) * sizeof(bool));
353  }
354 
355  /* error */
356  if (err_msg)
358  else
359  nulls[NUM_PG_HBA_FILE_RULES_ATTS - 1] = true;
360 
361  tuple = heap_form_tuple(tupdesc, values, nulls);
362  tuplestore_puttuple(tuple_store, tuple);
363 }
364 
365 /*
366  * fill_hba_view
367  * Read the pg_hba.conf file and fill the tuplestore with view records.
368  */
369 static void
371 {
372  FILE *file;
373  List *hba_lines = NIL;
374  ListCell *line;
375  int rule_number = 0;
376  MemoryContext hbacxt;
377  MemoryContext oldcxt;
378 
379  /*
380  * In the unlikely event that we can't open pg_hba.conf, we throw an
381  * error, rather than trying to report it via some sort of view entry.
382  * (Most other error conditions should result in a message in a view
383  * entry.)
384  */
385  file = open_auth_file(HbaFileName, ERROR, 0, NULL);
386 
387  tokenize_auth_file(HbaFileName, file, &hba_lines, DEBUG3, 0);
388 
389  /* Now parse all the lines */
391  "hba parser context",
393  oldcxt = MemoryContextSwitchTo(hbacxt);
394  foreach(line, hba_lines)
395  {
396  TokenizedAuthLine *tok_line = (TokenizedAuthLine *) lfirst(line);
397  HbaLine *hbaline = NULL;
398 
399  /* don't parse lines that already have errors */
400  if (tok_line->err_msg == NULL)
401  hbaline = parse_hba_line(tok_line, DEBUG3);
402 
403  /* No error, set a new rule number */
404  if (tok_line->err_msg == NULL)
405  rule_number++;
406 
407  fill_hba_line(tuple_store, tupdesc, rule_number,
408  tok_line->file_name, tok_line->line_num, hbaline,
409  tok_line->err_msg);
410  }
411 
412  /* Free tokenizer memory */
413  free_auth_file(file, 0);
414  /* Free parse_hba_line memory */
415  MemoryContextSwitchTo(oldcxt);
416  MemoryContextDelete(hbacxt);
417 }
418 
419 /*
420  * pg_hba_file_rules
421  *
422  * SQL-accessible set-returning function to return all the entries in the
423  * pg_hba.conf file.
424  */
425 Datum
427 {
428  ReturnSetInfo *rsi;
429 
430  /*
431  * Build tuplestore to hold the result rows. We must use the Materialize
432  * mode to be safe against HBA file changes while the cursor is open. It's
433  * also more efficient than having to look up our current position in the
434  * parsed list every time.
435  */
436  InitMaterializedSRF(fcinfo, 0);
437 
438  /* Fill the tuplestore */
439  rsi = (ReturnSetInfo *) fcinfo->resultinfo;
440  fill_hba_view(rsi->setResult, rsi->setDesc);
441 
442  PG_RETURN_NULL();
443 }
444 
445 /* Number of columns in pg_ident_file_mappings view */
446 #define NUM_PG_IDENT_FILE_MAPPINGS_ATTS 7
447 
448 /*
449  * fill_ident_line: build one row of pg_ident_file_mappings view, add it to
450  * tuplestore
451  *
452  * tuple_store: where to store data
453  * tupdesc: tuple descriptor for the view
454  * map_number: unique identifier among all valid maps
455  * filename: configuration file name (must always be valid)
456  * lineno: line number of configuration file (must always be valid)
457  * ident: parsed line data (can be NULL, in which case err_msg should be set)
458  * err_msg: error message (NULL if none)
459  *
460  * Note: leaks memory, but we don't care since this is run in a short-lived
461  * memory context.
462  */
463 static void
465  int map_number, char *filename, int lineno, IdentLine *ident,
466  const char *err_msg)
467 {
470  HeapTuple tuple;
471  int index;
472 
474 
475  memset(values, 0, sizeof(values));
476  memset(nulls, 0, sizeof(nulls));
477  index = 0;
478 
479  /* map_number, nothing on error */
480  if (err_msg)
481  nulls[index++] = true;
482  else
483  values[index++] = Int32GetDatum(map_number);
484 
485  /* file_name */
487 
488  /* line_number */
489  values[index++] = Int32GetDatum(lineno);
490 
491  if (ident != NULL)
492  {
493  values[index++] = CStringGetTextDatum(ident->usermap);
494  values[index++] = CStringGetTextDatum(ident->system_user->string);
495  values[index++] = CStringGetTextDatum(ident->pg_user->string);
496  }
497  else
498  {
499  /* no parsing result, so set relevant fields to nulls */
500  memset(&nulls[3], true, (NUM_PG_IDENT_FILE_MAPPINGS_ATTS - 4) * sizeof(bool));
501  }
502 
503  /* error */
504  if (err_msg)
506  else
507  nulls[NUM_PG_IDENT_FILE_MAPPINGS_ATTS - 1] = true;
508 
509  tuple = heap_form_tuple(tupdesc, values, nulls);
510  tuplestore_puttuple(tuple_store, tuple);
511 }
512 
513 /*
514  * Read the pg_ident.conf file and fill the tuplestore with view records.
515  */
516 static void
518 {
519  FILE *file;
520  List *ident_lines = NIL;
521  ListCell *line;
522  int map_number = 0;
523  MemoryContext identcxt;
524  MemoryContext oldcxt;
525 
526  /*
527  * In the unlikely event that we can't open pg_ident.conf, we throw an
528  * error, rather than trying to report it via some sort of view entry.
529  * (Most other error conditions should result in a message in a view
530  * entry.)
531  */
532  file = open_auth_file(IdentFileName, ERROR, 0, NULL);
533 
534  tokenize_auth_file(IdentFileName, file, &ident_lines, DEBUG3, 0);
535 
536  /* Now parse all the lines */
538  "ident parser context",
540  oldcxt = MemoryContextSwitchTo(identcxt);
541  foreach(line, ident_lines)
542  {
543  TokenizedAuthLine *tok_line = (TokenizedAuthLine *) lfirst(line);
544  IdentLine *identline = NULL;
545 
546  /* don't parse lines that already have errors */
547  if (tok_line->err_msg == NULL)
548  identline = parse_ident_line(tok_line, DEBUG3);
549 
550  /* no error, set a new mapping number */
551  if (tok_line->err_msg == NULL)
552  map_number++;
553 
554  fill_ident_line(tuple_store, tupdesc, map_number,
555  tok_line->file_name, tok_line->line_num,
556  identline, tok_line->err_msg);
557  }
558 
559  /* Free tokenizer memory */
560  free_auth_file(file, 0);
561  /* Free parse_ident_line memory */
562  MemoryContextSwitchTo(oldcxt);
563  MemoryContextDelete(identcxt);
564 }
565 
566 /*
567  * SQL-accessible SRF to return all the entries in the pg_ident.conf file.
568  */
569 Datum
571 {
572  ReturnSetInfo *rsi;
573 
574  /*
575  * Build tuplestore to hold the result rows. We must use the Materialize
576  * mode to be safe against HBA file changes while the cursor is open. It's
577  * also more efficient than having to look up our current position in the
578  * parsed list every time.
579  */
580  InitMaterializedSRF(fcinfo, 0);
581 
582  /* Fill the tuplestore */
583  rsi = (ReturnSetInfo *) fcinfo->resultinfo;
584  fill_ident_view(rsi->setResult, rsi->setDesc);
585 
586  PG_RETURN_NULL();
587 }
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
Definition: arrayfuncs.c:3374
static Datum values[MAXATTR]
Definition: bootstrap.c:152
#define CStringGetTextDatum(s)
Definition: builtins.h:97
#define Assert(condition)
Definition: c.h:858
#define DEBUG3
Definition: elog.h:28
#define ERROR
Definition: elog.h:39
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
Definition: funcapi.c:76
char * HbaFileName
Definition: guc_tables.c:542
char * IdentFileName
Definition: guc_tables.c:543
IdentLine * parse_ident_line(TokenizedAuthLine *tok_line, int elevel)
Definition: hba.c:2689
FILE * open_auth_file(const char *filename, int elevel, int depth, char **err_msg)
Definition: hba.c:595
const char * hba_authname(UserAuth auth_method)
Definition: hba.c:3061
void free_auth_file(FILE *file, int depth)
Definition: hba.c:570
HbaLine * parse_hba_line(TokenizedAuthLine *tok_line, int elevel)
Definition: hba.c:1322
void tokenize_auth_file(const char *filename, FILE *file, List **tok_lines, int elevel, int depth)
Definition: hba.c:686
@ ipCmpAll
Definition: hba.h:54
@ ipCmpSameNet
Definition: hba.h:53
@ ipCmpMask
Definition: hba.h:51
@ ipCmpSameHost
Definition: hba.h:52
@ ctHostNoGSS
Definition: hba.h:64
@ ctHostSSL
Definition: hba.h:61
@ ctHostNoSSL
Definition: hba.h:62
@ ctHost
Definition: hba.h:60
@ ctHostGSS
Definition: hba.h:63
@ ctLocal
Definition: hba.h:59
@ uaLDAP
Definition: hba.h:38
@ uaGSS
Definition: hba.h:34
@ uaRADIUS
Definition: hba.h:40
@ uaSSPI
Definition: hba.h:35
@ clientCertOff
Definition: hba.h:69
@ clientCertCA
Definition: hba.h:70
static void fill_ident_line(Tuplestorestate *tuple_store, TupleDesc tupdesc, int map_number, char *filename, int lineno, IdentLine *ident, const char *err_msg)
Definition: hbafuncs.c:464
static void fill_hba_view(Tuplestorestate *tuple_store, TupleDesc tupdesc)
Definition: hbafuncs.c:370
static void fill_ident_view(Tuplestorestate *tuple_store, TupleDesc tupdesc)
Definition: hbafuncs.c:517
static void fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc, int rule_number, char *filename, int lineno, HbaLine *hba, const char *err_msg)
Definition: hbafuncs.c:179
#define NUM_PG_HBA_FILE_RULES_ATTS
Definition: hbafuncs.c:161
static ArrayType * get_hba_options(HbaLine *hba)
Definition: hbafuncs.c:52
Datum pg_ident_file_mappings(PG_FUNCTION_ARGS)
Definition: hbafuncs.c:570
#define MAX_HBA_OPTIONS
Definition: hbafuncs.c:45
#define NUM_PG_IDENT_FILE_MAPPINGS_ATTS
Definition: hbafuncs.c:446
Datum pg_hba_file_rules(PG_FUNCTION_ARGS)
Definition: hbafuncs.c:426
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1116
#define ident
Definition: indent_codes.h:47
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
Definition: ip.c:114
List * lappend(List *list, void *datum)
Definition: list.c:339
char * pstrdup(const char *in)
Definition: mcxt.c:1695
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_SMALL_SIZES
Definition: memutils.h:170
void clean_ipv6_addr(int addr_family, char *addr)
Definition: network.c:2095
ArrayType * strlist_to_textarray(List *list)
static char * filename
Definition: pg_dumpall.c:119
#define lfirst(lc)
Definition: pg_list.h:172
#define NIL
Definition: pg_list.h:68
static size_t noptions
static char ** options
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
uintptr_t Datum
Definition: postgres.h:64
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
MemoryContextSwitchTo(old_ctx)
Definition: hba.h:88
char * string
Definition: hba.h:89
Definition: hba.h:95
UserAuth auth_method
Definition: hba.h:108
struct sockaddr_storage mask
Definition: hba.h:104
int addrlen
Definition: hba.h:103
char * ldapserver
Definition: hba.h:114
bool include_realm
Definition: hba.h:127
int masklen
Definition: hba.h:105
ClientCertMode clientcert
Definition: hba.h:124
char * ldapsearchfilter
Definition: hba.h:119
char * ldapprefix
Definition: hba.h:122
char * ldapsearchattribute
Definition: hba.h:118
char * krb_realm
Definition: hba.h:126
char * ldapbasedn
Definition: hba.h:120
char * radiussecrets_s
Definition: hba.h:133
char * hostname
Definition: hba.h:107
char * pamservice
Definition: hba.h:110
List * databases
Definition: hba.h:100
ConnType conntype
Definition: hba.h:99
char * usermap
Definition: hba.h:109
char * ldapsuffix
Definition: hba.h:123
int ldapport
Definition: hba.h:115
struct sockaddr_storage addr
Definition: hba.h:102
char * ldapbindpasswd
Definition: hba.h:117
List * roles
Definition: hba.h:101
char * radiusports_s
Definition: hba.h:137
char * ldapbinddn
Definition: hba.h:116
int ldapscope
Definition: hba.h:121
IPCompareMethod ip_cmp_method
Definition: hba.h:106
bool ldaptls
Definition: hba.h:112
char * radiusservers_s
Definition: hba.h:131
char * radiusidentifiers_s
Definition: hba.h:135
Definition: hba.h:141
Definition: pg_list.h:54
TupleDesc setDesc
Definition: execnodes.h:340
Tuplestorestate * setResult
Definition: execnodes.h:339
int line_num
Definition: hba.h:162
char * file_name
Definition: hba.h:161
char * err_msg
Definition: hba.h:164
Definition: type.h:95
void tuplestore_puttuple(Tuplestorestate *state, HeapTuple tuple)
Definition: tuplestore.c:730