Security_admin.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "admin/Admin.h"
  16. #include "benc/String.h"
  17. #include "benc/Dict.h"
  18. #include "rust/cjdns_sys/RTypes.h"
  19. #include "rust/cjdns_sys/Rffi.h"
  20. #include "util/log/Log.h"
  21. #include "util/Security.h"
  22. #include "util/Security_admin.h"
  23. struct Context
  24. {
  25. struct Log* logger;
  26. struct Admin* admin;
  27. struct Security* sec;
  28. Identity
  29. };
  30. static void sendError(RTypes_Error_t* er, String* txid, struct Admin* admin, Allocator_t* requestAlloc)
  31. {
  32. char* msg = "none";
  33. if (er) {
  34. msg = Rffi_printError(er, requestAlloc);
  35. }
  36. Dict error = Dict_CONST(String_CONST("error"),
  37. String_OBJ(String_CONST(msg)), NULL);
  38. Admin_sendMessage(&error, txid, admin);
  39. }
  40. static void setUser(Dict* args, void* vctx, String* txid, struct Allocator* requestAlloc)
  41. {
  42. struct Context* const ctx = Identity_check((struct Context*) vctx);
  43. int64_t* user = Dict_getIntC(args, "uid");
  44. int64_t* group = Dict_getIntC(args, "gid");
  45. int gid = group ? (int)*group : 0;
  46. int64_t* keepNetAdmin = Dict_getIntC(args, "keepNetAdmin");
  47. RTypes_Error_t* er = Security_setUser(*user, gid, *keepNetAdmin, ctx->logger, requestAlloc);
  48. if (er) {
  49. sendError(er, txid, ctx->admin, requestAlloc);
  50. return;
  51. }
  52. sendError(NULL, txid, ctx->admin, requestAlloc);
  53. }
  54. static void checkPermissions(Dict* args, void* vctx, String* txid, struct Allocator* requestAlloc)
  55. {
  56. struct Context* const ctx = Identity_check((struct Context*) vctx);
  57. struct Security_Permissions* sp = NULL;
  58. RTypes_Error_t* er = Security_checkPermissions(&sp, requestAlloc);
  59. if (er) {
  60. sendError(er, txid, ctx->admin, requestAlloc);
  61. return;
  62. }
  63. Dict* out = Dict_new(requestAlloc);
  64. Dict_putIntC(out, "noOpenFiles", sp->noOpenFiles, requestAlloc);
  65. Dict_putIntC(out, "userId", sp->uid, requestAlloc);
  66. Dict_putStringCC(out, "error", "none", requestAlloc);
  67. Admin_sendMessage(out, txid, ctx->admin);
  68. }
  69. static void nofiles(Dict* args, void* vctx, String* txid, struct Allocator* requestAlloc)
  70. {
  71. struct Context* const ctx = Identity_check((struct Context*) vctx);
  72. RTypes_Error_t* er = Security_nofiles(requestAlloc);
  73. if (er) {
  74. sendError(er, txid, ctx->admin, requestAlloc);
  75. return;
  76. }
  77. sendError(NULL, txid, ctx->admin, requestAlloc);
  78. }
  79. static void noforks(Dict* args, void* vctx, String* txid, struct Allocator* requestAlloc)
  80. {
  81. struct Context* const ctx = Identity_check((struct Context*) vctx);
  82. RTypes_Error_t* er = Security_noforks(requestAlloc);
  83. if (er) {
  84. sendError(er, txid, ctx->admin, requestAlloc);
  85. return;
  86. }
  87. sendError(NULL, txid, ctx->admin, requestAlloc);
  88. }
  89. static void chroot(Dict* args, void* vctx, String* txid, struct Allocator* requestAlloc)
  90. {
  91. struct Context* const ctx = Identity_check((struct Context*) vctx);
  92. String* root = Dict_getStringC(args, "root");
  93. RTypes_Error_t* er = Security_chroot(root->bytes, requestAlloc);
  94. if (er) {
  95. sendError(er, txid, ctx->admin, requestAlloc);
  96. return;
  97. }
  98. sendError(NULL, txid, ctx->admin, requestAlloc);
  99. }
  100. static void setupComplete(Dict* args, void* vctx, String* txid, struct Allocator* requestAlloc)
  101. {
  102. struct Context* const ctx = Identity_check((struct Context*) vctx);
  103. Security_setupComplete(ctx->sec);
  104. sendError(NULL, txid, ctx->admin, requestAlloc);
  105. }
  106. static void getUser(Dict* args, void* vctx, String* txid, struct Allocator* requestAlloc)
  107. {
  108. struct Context* const ctx = Identity_check((struct Context*) vctx);
  109. String* user = Dict_getStringC(args, "user");
  110. Dict* ret = Security_getUser((user) ? user->bytes : NULL, requestAlloc);
  111. Admin_sendMessage(ret, txid, ctx->admin);
  112. }
  113. void Security_admin_register(struct Allocator* alloc,
  114. struct Log* logger,
  115. struct Security* sec,
  116. struct Admin* admin)
  117. {
  118. struct Context* ctx = Allocator_clone(alloc, (&(struct Context) {
  119. .logger = logger,
  120. .admin = admin
  121. }));
  122. Identity_set(ctx);
  123. ctx->sec = sec;
  124. Admin_registerFunction("Security_nofiles", nofiles, ctx, true, NULL, admin);
  125. Admin_registerFunction("Security_noforks", noforks, ctx, true, NULL, admin);
  126. Admin_registerFunction("Security_chroot", chroot, ctx, true, ((struct Admin_FunctionArg[]) {
  127. { .name = "root", .required = 1, .type = "String" }
  128. }), admin);
  129. Admin_registerFunction("Security_setUser", setUser, ctx, true, ((struct Admin_FunctionArg[]) {
  130. { .name = "uid", .required = 1, .type = "Int" },
  131. { .name = "gid", .required = 0, .type = "Int" },
  132. { .name = "keepNetAdmin", .required = 1, .type = "Int" },
  133. }), admin);
  134. Admin_registerFunction("Security_getUser", getUser, ctx, true, ((struct Admin_FunctionArg[]) {
  135. { .name = "user", .required = 0, .type = "String" }
  136. }), admin);
  137. Admin_registerFunction("Security_setupComplete", setupComplete, ctx, true, NULL, admin);
  138. Admin_registerFunction("Security_checkPermissions", checkPermissions, ctx, true, NULL, admin);
  139. }