MCPcopy Create free account
hub / github.com/F-Stack/f-stack / ACLDescribeUserCommandRules

Function ACLDescribeUserCommandRules

app/redis-6.2.6/src/acl.c:464–603  ·  view source on GitHub ↗

This function returns an SDS string representing the specified user ACL * rules related to command execution, in the same format you could set them * back using ACL SETUSER. The function will return just the set of rules needed * to recreate the user commands bitmap, without including other user flags such * as on/off, passwords and so forth. The returned string always starts with * the +@all

Source from the content-addressed store, hash-verified

462 * the +@all or -@all rule, depending on the user bitmap, and is followed, if
463 * needed, by the other rules needed to narrow or extend what the user can do. */
464sds ACLDescribeUserCommandRules(user *u) {
465 sds rules = sdsempty();
466 int additive; /* If true we start from -@all and add, otherwise if
467 false we start from +@all and remove. */
468
469 /* This code is based on a trick: as we generate the rules, we apply
470 * them to a fake user, so that as we go we still know what are the
471 * bit differences we should try to address by emitting more rules. */
472 user fu = {0};
473 user *fakeuser = &fu;
474
475 /* Here we want to understand if we should start with +@all and remove
476 * the commands corresponding to the bits that are not set in the user
477 * commands bitmap, or the contrary. Note that semantically the two are
478 * different. For instance starting with +@all and subtracting, the user
479 * will be able to execute future commands, while -@all and adding will just
480 * allow the user the run the selected commands and/or categories.
481 * How do we test for that? We use the trick of a reserved command ID bit
482 * that is set only by +@all (and its alias "allcommands"). */
483 if (ACLUserCanExecuteFutureCommands(u)) {
484 additive = 0;
485 rules = sdscat(rules,"+@all ");
486 ACLSetUser(fakeuser,"+@all",-1);
487 } else {
488 additive = 1;
489 rules = sdscat(rules,"-@all ");
490 ACLSetUser(fakeuser,"-@all",-1);
491 }
492
493 /* Attempt to find a good approximation for categories and commands
494 * based on the current bits used, by looping over the category list
495 * and applying the best fit each time. Often a set of categories will not
496 * perfectly match the set of commands into it, so at the end we do a
497 * final pass adding/removing the single commands needed to make the bitmap
498 * exactly match. A temp user is maintained to keep track of categories
499 * already applied. */
500 user tu = {0};
501 user *tempuser = &tu;
502
503 /* Keep track of the categories that have been applied, to prevent
504 * applying them twice. */
505 char applied[sizeof(ACLCommandCategories)/sizeof(ACLCommandCategories[0])];
506 memset(applied, 0, sizeof(applied));
507
508 memcpy(tempuser->allowed_commands,
509 u->allowed_commands,
510 sizeof(u->allowed_commands));
511 while (1) {
512 int best = -1;
513 unsigned long mindiff = INT_MAX, maxsame = 0;
514 for (int j = 0; ACLCommandCategories[j].flag != 0; j++) {
515 if (applied[j]) continue;
516
517 unsigned long on, off, diff, same;
518 ACLCountCategoryBitsForUser(tempuser,&on,&off,ACLCommandCategories[j].name);
519 /* Check if the current category is the best this loop:
520 * * It has more commands in common with the user than commands
521 * that are different.

Callers 2

ACLDescribeUserFunction · 0.85
aclCommandFunction · 0.85

Calls 15

sdsemptyFunction · 0.85
sdscatFunction · 0.85
ACLSetUserFunction · 0.85
memsetFunction · 0.85
sdsnewlenFunction · 0.85
sdscatsdsFunction · 0.85
sdscatlenFunction · 0.85
sdsfreeFunction · 0.85
ACLGetUserCommandBitFunction · 0.85
ACLSetUserCommandBitFunction · 0.85

Tested by

no test coverage detected