Line data Source code
1 : /*
2 : SSSD
3 :
4 : PAM Responder
5 :
6 : Copyright (C) Red Hat 2015
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "util/util.h"
23 : #include "providers/data_provider.h"
24 : #include "responder/pam/pamsrv.h"
25 : #include "responder/common/responder_packet.h"
26 :
27 : static errno_t pack_user_info_account_expired(TALLOC_CTX *mem_ctx,
28 : const char *user_error_message,
29 : size_t *resp_len,
30 : uint8_t **_resp);
31 :
32 0 : errno_t pamsrv_exp_warn(struct pam_data *pd,
33 : int pam_verbosity,
34 : const char *exp_msg)
35 : {
36 : size_t msg_len;
37 : uint8_t *msg;
38 : errno_t ret;
39 :
40 0 : if (pd->pam_status == PAM_ACCT_EXPIRED &&
41 0 : ((pd->service != NULL && strcasecmp(pd->service, "sshd") == 0) ||
42 : pam_verbosity >= PAM_VERBOSITY_INFO)) {
43 :
44 0 : ret = pack_user_info_account_expired(pd, exp_msg, &msg_len, &msg);
45 0 : if (ret != EOK) {
46 0 : DEBUG(SSSDBG_CRIT_FAILURE,
47 : "pack_user_info_account_expired failed.\n");
48 0 : return ret;
49 : } else {
50 0 : ret = pam_add_response(pd, SSS_PAM_USER_INFO, msg_len, msg);
51 0 : if (ret != EOK) {
52 0 : DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
53 0 : return ret;
54 : }
55 : }
56 : }
57 :
58 0 : return EOK;
59 : }
60 :
61 0 : static errno_t pack_user_info_account_expired(TALLOC_CTX *mem_ctx,
62 : const char *user_error_message,
63 : size_t *resp_len,
64 : uint8_t **_resp)
65 : {
66 0 : uint32_t resp_type = SSS_PAM_USER_INFO_ACCOUNT_EXPIRED;
67 : size_t err_len;
68 : uint8_t *resp;
69 : size_t p;
70 :
71 0 : err_len = strlen(user_error_message);
72 0 : *resp_len = 2 * sizeof(uint32_t) + err_len;
73 0 : resp = talloc_size(mem_ctx, *resp_len);
74 0 : if (resp == NULL) {
75 0 : DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n");
76 0 : return ENOMEM;
77 : }
78 :
79 0 : p = 0;
80 0 : SAFEALIGN_SET_UINT32(&resp[p], resp_type, &p);
81 0 : SAFEALIGN_SET_UINT32(&resp[p], err_len, &p);
82 0 : safealign_memcpy(&resp[p], user_error_message, err_len, &p);
83 0 : if (p != *resp_len) {
84 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Size mismatch\n");
85 : }
86 :
87 0 : *_resp = resp;
88 0 : return EOK;
89 : }
90 :
91 47 : errno_t pamsrv_reply_packet(TALLOC_CTX *mem_ctx,
92 : struct pam_data *pd,
93 : enum sss_cli_command cmd,
94 : struct sss_packet **_out)
95 : {
96 : errno_t ret;
97 : uint8_t *body;
98 : size_t blen;
99 : int32_t resp_c;
100 : int32_t resp_size;
101 : struct response_data *resp;
102 : int p;
103 : struct sss_packet *out;
104 :
105 47 : ret = sss_packet_new(mem_ctx, 0, cmd, &out);
106 47 : if (ret != EOK) {
107 0 : goto done;
108 : }
109 :
110 47 : resp_c = 0;
111 47 : resp_size = 0;
112 47 : resp = pd->resp_list;
113 133 : while(resp != NULL) {
114 39 : if (!resp->do_not_send_to_client) {
115 34 : resp_c++;
116 34 : resp_size += resp->len;
117 : }
118 39 : resp = resp->next;
119 : }
120 :
121 47 : ret = sss_packet_grow(out, sizeof(int32_t) + sizeof(int32_t) +
122 : resp_c * 2 * sizeof(int32_t) + resp_size);
123 47 : if (ret != EOK) {
124 0 : goto done;
125 : }
126 :
127 47 : sss_packet_get_body(out, &body, &blen);
128 47 : DEBUG(SSSDBG_FUNC_DATA, "blen: %zu\n", blen);
129 47 : p = 0;
130 :
131 47 : memcpy(&body[p], &pd->pam_status, sizeof(int32_t));
132 47 : p += sizeof(int32_t);
133 :
134 47 : memcpy(&body[p], &resp_c, sizeof(int32_t));
135 47 : p += sizeof(int32_t);
136 :
137 47 : resp = pd->resp_list;
138 133 : while(resp != NULL) {
139 39 : if (!resp->do_not_send_to_client) {
140 34 : memcpy(&body[p], &resp->type, sizeof(int32_t));
141 34 : p += sizeof(int32_t);
142 34 : memcpy(&body[p], &resp->len, sizeof(int32_t));
143 34 : p += sizeof(int32_t);
144 34 : memcpy(&body[p], resp->data, resp->len);
145 34 : p += resp->len;
146 : }
147 :
148 39 : resp = resp->next;
149 : }
150 :
151 47 : *_out = out;
152 47 : ret = EOK;
153 :
154 : done:
155 47 : return ret;
156 : }
|