PostgreSQL Source Code: src/bin/pg_dump/dumputils.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
16
17#include <ctype.h>
18
23
24
26 const char *name, const char *subname, int remoteVersion,
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65bool
67 const char *type, const char *acls, const char *baseacls,
68 const char *owner, const char *prefix, int remoteVersion,
70{
71 bool ok = true;
72 char **aclitems = NULL;
73 char **baseitems = NULL;
74 char **grantitems = NULL;
75 char **revokeitems = NULL;
76 int naclitems = 0;
77 int nbaseitems = 0;
78 int ngrantitems = 0;
79 int nrevokeitems = 0;
80 int i;
82 grantor,
83 privs,
84 privswgo;
86 secondsql;
87
88
89
90
91
92
93 if (acls == NULL || *acls == '\0')
94 return true;
95
96
97 if (owner && *owner == '\0')
98 owner = NULL;
99
100
101 if ((acls, &aclitems, &naclitems))
102 {
103 free(aclitems);
104 return false;
105 }
106
107
108 if ((baseacls, &baseitems, &nbaseitems))
109 {
110 free(aclitems);
111 free(baseitems);
112 return false;
113 }
114
115
116
117
118
119
120
121
122
123
124
125 grantitems = (char **) pg_malloc(naclitems * sizeof(char *));
126 for (i = 0; i < naclitems; i++)
127 {
128 bool found = false;
129
130 for (int j = 0; j < nbaseitems; j++)
131 {
132 if (strcmp(aclitems[i], baseitems[j]) == 0)
133 {
134 found = true;
135 break;
136 }
137 }
138 if (!found)
139 grantitems[ngrantitems++] = aclitems[i];
140 }
141 revokeitems = (char **) pg_malloc(nbaseitems * sizeof(char *));
142 for (i = 0; i < nbaseitems; i++)
143 {
144 bool found = false;
145
146 for (int j = 0; j < naclitems; j++)
147 {
148 if (strcmp(baseitems[i], aclitems[j]) == 0)
149 {
150 found = true;
151 break;
152 }
153 }
154 if (!found)
155 revokeitems[nrevokeitems++] = baseitems[i];
156 }
157
158
163
164
165
166
169
170
171
172
173 for (i = 0; i < nrevokeitems; i++)
174 {
177 grantee, grantor, privs, NULL))
178 {
179 ok = false;
180 break;
181 }
182
183 if (privs->len > 0)
184 {
187 if (nspname && *nspname)
192 if (grantee->len == 0)
194 else
197 }
198 }
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223 for (i = 0; i < ngrantitems; i++)
224 {
226 grantee, grantor, privs, privswgo))
227 {
228
229
230
231
232
233 if (privs->len > 0 || privswgo->len > 0)
234 {
236
237
238 if (grantor->len == 0 && owner)
240
241
242 if (owner &&
243 strcmp(grantee->data, owner) == 0 &&
244 strcmp(grantor->data, owner) == 0)
245 thissql = firstsql;
246 else
247 thissql = secondsql;
248
249 if (grantor->len > 0
250 && (!owner || strcmp(owner, grantor->data) != 0))
253
254 if (privs->len > 0)
255 {
258 if (nspname && *nspname)
263 if (grantee->len == 0)
265 else
267 }
268 if (privswgo->len > 0)
269 {
271 prefix, privswgo->data, type);
272 if (nspname && *nspname)
277 if (grantee->len == 0)
279 else
282 }
283
284 if (grantor->len > 0
285 && (!owner || strcmp(owner, grantor->data) != 0))
287 }
288 }
289 else
290 {
291
292 ok = false;
293 break;
294 }
295 }
296
301
305
306 free(aclitems);
307 free(baseitems);
308 free(grantitems);
309 free(revokeitems);
310
311 return ok;
312}
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327bool
329 const char *acls, const char *acldefault,
330 const char *owner,
331 int remoteVersion,
333{
335
337
338
339
340
341
342
343
344 appendPQExpBuffer(prefix, "ALTER DEFAULT PRIVILEGES FOR ROLE %s ",
346 if (nspname)
348
349
350
351
352
355 prefix->data, remoteVersion, sql))
356 {
358 return false;
359 }
360
362
363 return true;
364}
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384static bool
386 const char *name, const char *subname, int remoteVersion,
389{
390 char *buf;
391 bool all_with_go = true;
392 bool all_without_go = true;
393 char *eqpos;
394 char *slpos;
395 char *pos;
396
398
399
401 if (*eqpos != '=')
402 {
404 return false;
405 }
406
407
408 slpos = strchr(eqpos + 1, '/');
409 if (slpos)
410 {
411 *slpos++ = '\0';
413 if (*slpos != '\0')
414 {
416 return false;
417 }
418 }
419 else
420 {
422 return false;
423 }
424
425
426#define CONVERT_PRIV(code, keywd) \
427do { \
428 if ((pos = strchr(eqpos + 1, code))) \
429 { \
430 if (*(pos + 1) == '*' && privswgo != NULL) \
431 { \
432 AddAcl(privswgo, keywd, subname); \
433 all_without_go = false; \
434 } \
435 else \
436 { \
437 AddAcl(privs, keywd, subname); \
438 all_with_go = false; \
439 } \
440 } \
441 else \
442 all_with_go = all_without_go = false; \
443} while (0)
444
447
448 if (strcmp(type, "TABLE") == 0 || strcmp(type, "SEQUENCE") == 0 ||
449 strcmp(type, "TABLES") == 0 || strcmp(type, "SEQUENCES") == 0)
450 {
452
453 if (strcmp(type, "SEQUENCE") == 0 ||
454 strcmp(type, "SEQUENCES") == 0)
455
457 else
458 {
459
462
464 {
469 }
470 }
471
472
474 }
475 else if (strcmp(type, "FUNCTION") == 0 ||
476 strcmp(type, "FUNCTIONS") == 0)
478 else if (strcmp(type, "PROCEDURE") == 0 ||
479 strcmp(type, "PROCEDURES") == 0)
481 else if (strcmp(type, "LANGUAGE") == 0)
483 else if (strcmp(type, "SCHEMA") == 0 ||
484 strcmp(type, "SCHEMAS") == 0)
485 {
488 }
489 else if (strcmp(type, "DATABASE") == 0)
490 {
494 }
495 else if (strcmp(type, "TABLESPACE") == 0)
497 else if (strcmp(type, "TYPE") == 0 ||
498 strcmp(type, "TYPES") == 0)
500 else if (strcmp(type, "FOREIGN DATA WRAPPER") == 0)
502 else if (strcmp(type, "FOREIGN SERVER") == 0)
504 else if (strcmp(type, "FOREIGN TABLE") == 0)
506 else if (strcmp(type, "PARAMETER") == 0)
507 {
510 }
511 else if (strcmp(type, "LARGE OBJECT") == 0 ||
512 strcmp(type, "LARGE OBJECTS") == 0)
513 {
516 }
517 else
518 abort();
519
520#undef CONVERT_PRIV
521
522 if (all_with_go)
523 {
528 }
529 else if (all_without_go)
530 {
535 }
536
538
539 return true;
540}
541
542
543
544
545
546void
548{
549 const char *src;
550 bool safe = true;
551
552 for (src = input; *src; src++)
553 {
554
555 if (!isalnum((unsigned char) *src) && *src != '_')
556 {
557 safe = false;
558 break;
559 }
560 }
561 if (!safe)
563 for (src = input; *src; src++)
564 {
565
566 if (*src == '"')
569 }
570 if (!safe)
572}
573
574
575
576
577
578
579
580static char *
582{
584
586 {
587
588
589
590 if (*input != '"')
592 else
593 {
594
596
597 while (!(*input == '"' && *(input + 1) != '"'))
598 {
599 if (*input == '\0')
600 return input;
601
602
603
604
605
606 if (*input == '"' && *(input + 1) == '"')
609 }
611 }
612 }
614}
615
616
617
618
619static void
621{
622 if (aclbuf->len > 0)
627}
628
629
630
631
632
633
634
635
636
637
638
639void
642{
644 "SELECT provider, label FROM pg_catalog.pg_shseclabel "
645 "WHERE classoid = 'pg_catalog.%s'::pg_catalog.regclass "
646 "AND objoid = '%u'", catalog_name, objectId);
647}
648
649
650
651
652
653
654
655
656
657void
659 const char *objtype, const char *objname)
660{
661 int i;
662
664 {
667
668
670 "SECURITY LABEL FOR %s ON %s",
673 " %s IS ",
677 }
678}
679
680
681
682
683
684
685
686
687
688
689
690
691bool
693{
700 return true;
701 else
702 return false;
703}
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725bool
727 char ***namelist)
728{
729 char *nextp = rawstring;
730 bool done = false;
731 char **nextptr;
732
733
734
735
736
737
738 *namelist = nextptr = (char **)
739 pg_malloc((strlen(rawstring) / 2 + 2) * sizeof(char *));
740 *nextptr = NULL;
741
742 while (isspace((unsigned char) *nextp))
743 nextp++;
744
745 if (*nextp == '\0')
746 return true;
747
748
749 do
750 {
751 char *curname;
752 char *endp;
753
754 if (*nextp == '"')
755 {
756
757 curname = nextp + 1;
758 for (;;)
759 {
760 endp = strchr(nextp + 1, '"');
761 if (endp == NULL)
762 return false;
763 if (endp[1] != '"')
764 break;
765
766 memmove(endp, endp + 1, strlen(endp));
767 nextp = endp;
768 }
769
770 nextp = endp + 1;
771 }
772 else
773 {
774
775 curname = nextp;
776 while (*nextp && *nextp != separator &&
777 !isspace((unsigned char) *nextp))
778 nextp++;
779 endp = nextp;
780 if (curname == nextp)
781 return false;
782 }
783
784 while (isspace((unsigned char) *nextp))
785 nextp++;
786
788 {
789 nextp++;
790 while (isspace((unsigned char) *nextp))
791 nextp++;
792
793 }
794 else if (*nextp == '\0')
795 done = true;
796 else
797 return false;
798
799
800 *endp = '\0';
801
802
803
804
805 *nextptr++ = curname;
806
807
808 } while (!done);
809
810 *nextptr = NULL;
811 return true;
812}
813
814
815
816
817
818
819
820
821
822
823
824
825void
827 const char *type, const char *name,
828 const char *type2, const char *name2,
830{
831 char *mine;
832 char *pos;
833
834
836 pos = strchr(mine, '=');
837 if (pos == NULL)
838 {
840 return;
841 }
842 *pos++ = '\0';
843
844
846 if (type2 != NULL && name2 != NULL)
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
865 {
866 char **namelist;
867 char **nameptr;
868
869
870
872 {
873 for (nameptr = namelist; *nameptr; nameptr++)
874 {
875 if (nameptr != namelist)
878 }
879 }
881 }
882 else
884
886
888}
889
890
891
892
893
894
895
896void
898{
899 int ret;
900
902 {
903 case -1:
904
905 pg_fatal("could not open directory \"%s\": %m", dirname);
906 break;
907 case 0:
908
910 pg_fatal("could not create directory \"%s\": %m", dirname);
911 break;
912 case 1:
913
915 pg_fatal("could not change permissions of directory \"%s\": %m",
916 dirname);
917 break;
918 default:
919
920 pg_fatal("directory \"%s\" is not empty", dirname);
921 }
922}
Acl * acldefault(ObjectType objtype, Oid ownerId)
bool buildACLCommands(const char *name, const char *subname, const char *nspname, const char *type, const char *acls, const char *baseacls, const char *owner, const char *prefix, int remoteVersion, PQExpBuffer sql)
static char * dequoteAclUserName(PQExpBuffer output, char *input)
void buildShSecLabelQuery(const char *catalog_name, Oid objectId, PQExpBuffer sql)
void makeAlterConfigCommand(PGconn *conn, const char *configitem, const char *type, const char *name, const char *type2, const char *name2, PQExpBuffer buf)
bool buildDefaultACLCommands(const char *type, const char *nspname, const char *acls, const char *acldefault, const char *owner, int remoteVersion, PQExpBuffer sql)
void create_or_open_dir(const char *dirname)
bool variable_is_guc_list_quote(const char *name)
void quoteAclUserName(PQExpBuffer output, const char *input)
static bool parseAclItem(const char *item, const char *type, const char *name, const char *subname, int remoteVersion, PQExpBuffer grantee, PQExpBuffer grantor, PQExpBuffer privs, PQExpBuffer privswgo)
static void AddAcl(PQExpBuffer aclbuf, const char *keyword, const char *subname)
void emitShSecLabels(PGconn *conn, PGresult *res, PQExpBuffer buffer, const char *objtype, const char *objname)
bool SplitGUCList(char *rawstring, char separator, char ***namelist)
#define CONVERT_PRIV(code, keywd)
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
int PQntuples(const PGresult *res)
void * pg_malloc(size_t size)
char * pg_strdup(const char *in)
int pg_strcasecmp(const char *s1, const char *s2)
int pg_check_dir(const char *dir)
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
void resetPQExpBuffer(PQExpBuffer str)
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
void destroyPQExpBuffer(PQExpBuffer str)
void appendPQExpBufferChar(PQExpBuffer str, char ch)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
const char * fmtId(const char *rawid)
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
bool parsePGArray(const char *atext, char ***itemarray, int *nitems)