PageRenderTime 25ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/src/helpers/creds-socket/creds-socket-inner.cpp

https://gitlab.com/admin-github-cloud/cynara
C++ | 115 lines | 74 code | 18 blank | 23 comment | 14 complexity | 60622c157db2150786c333e33aa4c14b MD5 | raw file
  1. /*
  2. * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License
  15. */
  16. /**
  17. * @file src/helpers/creds-socket/creds-socket-inner.cpp
  18. * @author Radoslaw Bartosiak <r.bartosiak@samsung.com>
  19. * @author Aleksander Zdyb <a.zdyb@samsung.com>
  20. * @author Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
  21. * @version 1.0
  22. * @brief Implementation of internal libcynara-creds-socket functions
  23. */
  24. #include <cerrno>
  25. #include <cstring>
  26. #include <string>
  27. #include <sys/socket.h>
  28. #include <sys/types.h>
  29. #include <exceptions/TryCatch.h>
  30. #include <cynara-error.h>
  31. #include "creds-socket-inner.h"
  32. int getClientSmackLabel(int socketFd, char **client) {
  33. char dummy;
  34. int ret;
  35. socklen_t length = 1;
  36. char *result;
  37. ret = getsockopt(socketFd, SOL_SOCKET, SO_PEERSEC, &dummy, &length);
  38. if ((ret < 0) && (errno != ERANGE))
  39. return CYNARA_API_INVALID_PARAM;
  40. result = static_cast<char*>(calloc(length + 1, sizeof(char)));
  41. if (result == nullptr)
  42. return CYNARA_API_OUT_OF_MEMORY;
  43. ret = getsockopt(socketFd, SOL_SOCKET, SO_PEERSEC, result, &length);
  44. if (ret < 0) {
  45. free(result);
  46. return CYNARA_API_INVALID_PARAM;
  47. }
  48. *client = result;
  49. return CYNARA_API_SUCCESS;
  50. }
  51. #define GET_CRED(SOCK, RESULT, CRED) \
  52. return Cynara::tryCatch([&]() { \
  53. struct ucred credentials; \
  54. int ret = getCredentials(SOCK, &credentials); \
  55. if (ret < 0) \
  56. return ret; \
  57. \
  58. *RESULT = strdup(std::to_string(credentials.CRED).c_str()); \
  59. if (*RESULT == nullptr) \
  60. return CYNARA_API_OUT_OF_MEMORY; \
  61. \
  62. return CYNARA_API_SUCCESS; \
  63. });
  64. int getClientPid(int socketFd, char **client) {
  65. GET_CRED(socketFd, client, pid)
  66. }
  67. int getUserId(int socketFd, char **user) {
  68. GET_CRED(socketFd, user, uid)
  69. }
  70. int getUserGid(int socketFd, char **user) {
  71. GET_CRED(socketFd, user, gid)
  72. }
  73. int getCredentials(int socketFd, struct ucred *credentials) {
  74. if (credentials == nullptr)
  75. return CYNARA_API_UNKNOWN_ERROR;
  76. int ret;
  77. socklen_t length = sizeof(struct ucred);
  78. ret = getsockopt(socketFd, SOL_SOCKET, SO_PEERCRED, credentials, &length);
  79. if (ret < 0) {
  80. switch (errno) {
  81. case EBADF:
  82. case ENOTSOCK:
  83. return CYNARA_API_INVALID_PARAM;
  84. default:
  85. return CYNARA_API_UNKNOWN_ERROR;
  86. }
  87. }
  88. return CYNARA_API_SUCCESS;
  89. }
  90. int getPid(int socketFd, pid_t *pid) {
  91. struct ucred credentials;
  92. int ret = getCredentials(socketFd, &credentials);
  93. if (ret < 0)
  94. return ret;
  95. *pid = credentials.pid;
  96. return CYNARA_API_SUCCESS;
  97. }