MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / ACLDescribeUserCommandRules

Function ACLDescribeUserCommandRules

src/acl.cpp:473–612  ·  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

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

Callers 2

ACLDescribeUserFunction · 0.85
aclCommandFunction · 0.85

Calls 15

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

Tested by

no test coverage detected