📄 acl.c
字号:
return 0; return ((a1->ai_idtype > a2->ai_idtype) || (a1->ai_idtype == a2->ai_idtype && a1->ai_id > a2->ai_id));}Acl *aclownerdefault(char *relname, AclId ownerid){ Acl *acl; AclItem *aip; acl = makeacl(2); aip = ACL_DAT(acl); aip[0].ai_idtype = ACL_IDTYPE_WORLD; aip[0].ai_id = ACL_ID_WORLD; aip[0].ai_mode = IsSystemRelationName(relname) ? ACL_RD : ACL_WORLD_DEFAULT; aip[1].ai_idtype = ACL_IDTYPE_UID; aip[1].ai_id = ownerid; aip[1].ai_mode = ACL_OWNER_DEFAULT; return acl;}Acl *acldefault(char *relname){ Acl *acl; AclItem *aip; acl = makeacl(1); aip = ACL_DAT(acl); aip[0].ai_idtype = ACL_IDTYPE_WORLD; aip[0].ai_id = ACL_ID_WORLD; aip[0].ai_mode = IsSystemRelationName(relname) ? ACL_RD : ACL_WORLD_DEFAULT; return acl;}Acl *aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg){ Acl *new_acl; AclItem *old_aip, *new_aip; unsigned src, dst, num; if (!old_acl || ACL_NUM(old_acl) < 1) { new_acl = makeacl(0); return new_acl; } if (!mod_aip) { new_acl = makeacl(ACL_NUM(old_acl)); memmove((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl)); return new_acl; } num = ACL_NUM(old_acl); old_aip = ACL_DAT(old_acl); /* * Search the ACL for an existing entry for 'id'. If one exists, just * modify the entry in-place (well, in the same position, since we * actually return a copy); otherwise, insert the new entry in * sort-order. */ /* find the first element not less than the element to be inserted */ for (dst = 0; dst < num && aclitemgt(mod_aip, old_aip + dst); ++dst) ; if (dst < num && aclitemeq(mod_aip, old_aip + dst)) { /* modify in-place */ new_acl = makeacl(ACL_NUM(old_acl)); memmove((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl)); new_aip = ACL_DAT(new_acl); src = dst; } else { new_acl = makeacl(num + 1); new_aip = ACL_DAT(new_acl); if (dst == 0) { /* start */ elog(ERROR, "aclinsert3: insertion before world ACL??"); } else if (dst >= num) { /* end */ memmove((char *) new_aip, (char *) old_aip, num * sizeof(AclItem)); } else { /* middle */ memmove((char *) new_aip, (char *) old_aip, dst * sizeof(AclItem)); memmove((char *) (new_aip + dst + 1), (char *) (old_aip + dst), (num - dst) * sizeof(AclItem)); } new_aip[dst].ai_id = mod_aip->ai_id; new_aip[dst].ai_idtype = mod_aip->ai_idtype; num++; /* set num to the size of new_acl */ src = 0; /* world entry */ } switch (modechg) { case ACL_MODECHG_ADD: new_aip[dst].ai_mode = old_aip[src].ai_mode | mod_aip->ai_mode; break; case ACL_MODECHG_DEL: new_aip[dst].ai_mode = old_aip[src].ai_mode & ~mod_aip->ai_mode; break; case ACL_MODECHG_EQL: new_aip[dst].ai_mode = mod_aip->ai_mode; break; } /* * if the newly added entry has no permissions, delete it from the * list. For example, this helps in removing entries for users who no * longer exists... */ for (dst = 1; dst < num; dst++) { if (new_aip[dst].ai_mode == 0) { int i; for (i = dst + 1; i < num; i++) { new_aip[i - 1].ai_id = new_aip[i].ai_id; new_aip[i - 1].ai_idtype = new_aip[i].ai_idtype; new_aip[i - 1].ai_mode = new_aip[i].ai_mode; } ARR_DIMS(new_acl)[0] = num - 1; /* Adjust also the array size because it is used for memmove */ ARR_SIZE(new_acl) -= sizeof(AclItem); break; } } return new_acl;}/* * aclinsert * */Acl *aclinsert(Acl *old_acl, AclItem *mod_aip){ return aclinsert3(old_acl, mod_aip, ACL_MODECHG_EQL);}Acl *aclremove(Acl *old_acl, AclItem *mod_aip){ Acl *new_acl; AclItem *old_aip, *new_aip; unsigned dst, old_num, new_num; if (!old_acl || ACL_NUM(old_acl) < 1) { new_acl = makeacl(0); return new_acl; } if (!mod_aip) { new_acl = makeacl(ACL_NUM(old_acl)); memmove((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl)); return new_acl; } old_num = ACL_NUM(old_acl); old_aip = ACL_DAT(old_acl); for (dst = 0; dst < old_num && !aclitemeq(mod_aip, old_aip + dst); ++dst) ; if (dst >= old_num) { /* not found or empty */ new_acl = makeacl(ACL_NUM(old_acl)); memmove((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl)); } else { new_num = old_num - 1; new_acl = makeacl(ACL_NUM(old_acl) - 1); new_aip = ACL_DAT(new_acl); if (dst == 0) { /* start */ elog(ERROR, "aclremove: removal of the world ACL??"); } else if (dst == old_num - 1) { /* end */ memmove((char *) new_aip, (char *) old_aip, new_num * sizeof(AclItem)); } else { /* middle */ memmove((char *) new_aip, (char *) old_aip, dst * sizeof(AclItem)); memmove((char *) (new_aip + dst), (char *) (old_aip + dst + 1), (new_num - dst) * sizeof(AclItem)); } } return new_acl;}int32aclcontains(Acl *acl, AclItem *aip){ unsigned i, num; AclItem *aidat; if (!acl || !aip || ((num = ACL_NUM(acl)) < 1)) return 0; aidat = ACL_DAT(acl); for (i = 0; i < num; ++i) if (aclitemeq(aip, aidat + i)) return 1; return 0;}/* parser support routines *//* * aclmakepriv * make a acl privilege string out of an existing privilege string * and a new privilege * * does not add duplicate privileges * */char *aclmakepriv(char *old_privlist, char new_priv){ char *priv; int i; int l; Assert(strlen(old_privlist) < 5); priv = palloc(5); /* at most "rwaR" */ ; if (old_privlist == NULL || old_privlist[0] == '\0') { priv[0] = new_priv; priv[1] = '\0'; return priv; } strcpy(priv, old_privlist); l = strlen(old_privlist); if (l == 4) { /* can't add any more privileges */ return priv; } /* check to see if the new privilege is already in the old string */ for (i = 0; i < l; i++) { if (priv[i] == new_priv) break; } if (i == l) { /* we really have a new privilege */ priv[l] = new_priv; priv[l + 1] = '\0'; } return priv;}/* * aclmakeuser * user_type must be "A" - all users * "G" - group * "U" - user * * concatentates the two strings together with a space in between * * this routine is used in the parser * */char *aclmakeuser(char *user_type, char *user){ char *user_list; user_list = palloc(strlen(user) + 3); sprintf(user_list, "%s %s", user_type, user); return user_list;}/* * makeAclStmt: * this is a helper routine called by the parser * create a ChangeAclStmt * we take in the privilegs, relation_name_list, and grantee * as well as a single character '+' or '-' to indicate grant or revoke * * returns a new ChangeACLStmt* * * this routines works by creating a old-style changle acl string and * then calling aclparse; */ChangeACLStmt *makeAclStmt(char *privileges, List *rel_list, char *grantee, char grant_or_revoke){ ChangeACLStmt *n = makeNode(ChangeACLStmt); char str[MAX_PARSE_BUFFER]; /* see comment in pg_type.h */ Assert(ACLITEMSIZE == sizeof(AclItem)); n->aclitem = (AclItem *) palloc(sizeof(AclItem)); /* the grantee string is "G <group_name>", "U <user_name>", or "ALL" */ if (grantee[0] == 'G') /* group permissions */ { sprintf(str, "%s %c%s%c%c%s", ACL_IDTYPE_GID_KEYWORD, '"', grantee + 2, '"', grant_or_revoke, privileges); } else if (grantee[0] == 'U') /* user permission */ { sprintf(str, "%s %c%s%c%c%s", ACL_IDTYPE_UID_KEYWORD, '"', grantee + 2, '"', grant_or_revoke, privileges); } else/* all permission */ { sprintf(str, "%c%s", grant_or_revoke, privileges); } n->relNames = rel_list; aclparse(str, n->aclitem, (unsigned *) &n->modechg); return n;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -