Line data Source code
1 : /*
2 : SSSD
3 :
4 : Kerberos 5 Backend Module
5 :
6 : Authors:
7 : Sumit Bose <sbose@redhat.com>
8 :
9 : Copyright (C) 2009 Red Hat
10 :
11 : This program is free software; you can redistribute it and/or modify
12 : it under the terms of the GNU General Public License as published by
13 : the Free Software Foundation; either version 3 of the License, or
14 : (at your option) any later version.
15 :
16 : This program is distributed in the hope that it will be useful,
17 : but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : GNU General Public License for more details.
20 :
21 : You should have received a copy of the GNU General Public License
22 : along with this program. If not, see <http://www.gnu.org/licenses/>.
23 : */
24 :
25 : #include <sys/types.h>
26 : #include <unistd.h>
27 : #include <fcntl.h>
28 : #include <sys/stat.h>
29 : #include "util/child_common.h"
30 : #include "providers/krb5/krb5_auth.h"
31 : #include "providers/krb5/krb5_common.h"
32 : #include "providers/krb5/krb5_init_shared.h"
33 : #include "providers/data_provider.h"
34 :
35 0 : static errno_t krb5_init_kpasswd(struct krb5_ctx *ctx,
36 : struct be_ctx *be_ctx)
37 : {
38 : const char *realm;
39 : const char *primary_servers;
40 : const char *backup_servers;
41 : const char *kdc_servers;
42 : bool use_kdcinfo;
43 : errno_t ret;
44 :
45 0 : realm = dp_opt_get_string(ctx->opts, KRB5_REALM);
46 0 : if (realm == NULL) {
47 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Missing krb5_realm option!\n");
48 0 : return EINVAL;
49 : }
50 :
51 0 : kdc_servers = dp_opt_get_string(ctx->opts, KRB5_KDC);
52 0 : primary_servers = dp_opt_get_string(ctx->opts, KRB5_KPASSWD);
53 0 : backup_servers = dp_opt_get_string(ctx->opts, KRB5_BACKUP_KPASSWD);
54 0 : use_kdcinfo = dp_opt_get_bool(ctx->opts, KRB5_USE_KDCINFO);
55 :
56 0 : if (primary_servers == NULL && backup_servers != NULL) {
57 0 : DEBUG(SSSDBG_CONF_SETTINGS, "kpasswd server wasn't specified but "
58 : "backup_servers kpasswd given. Using it as primary_servers\n");
59 0 : primary_servers = backup_servers;
60 0 : backup_servers = NULL;
61 : }
62 :
63 0 : if (primary_servers == NULL && kdc_servers != NULL) {
64 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Missing krb5_kpasswd option and KDC set "
65 : "explicitly, will use KDC for pasword change operations!\n");
66 0 : ctx->kpasswd_service = NULL;
67 : } else {
68 0 : ret = krb5_service_init(ctx, be_ctx, SSS_KRB5KPASSWD_FO_SRV,
69 : primary_servers, backup_servers, realm,
70 : use_kdcinfo, &ctx->kpasswd_service);
71 0 : if (ret != EOK) {
72 0 : DEBUG(SSSDBG_FATAL_FAILURE,
73 : "Failed to init KRB5KPASSWD failover service!\n");
74 0 : return ret;
75 : }
76 : }
77 :
78 0 : return EOK;
79 : }
80 :
81 0 : static errno_t krb5_init_kdc(struct krb5_ctx *ctx, struct be_ctx *be_ctx)
82 : {
83 : const char *primary_servers;
84 : const char *backup_servers;
85 : const char *realm;
86 : bool use_kdcinfo;
87 : errno_t ret;
88 :
89 0 : realm = dp_opt_get_string(ctx->opts, KRB5_REALM);
90 0 : if (realm == NULL) {
91 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Missing krb5_realm option!\n");
92 0 : return EINVAL;
93 : }
94 :
95 0 : primary_servers = dp_opt_get_string(ctx->opts, KRB5_KDC);
96 0 : backup_servers = dp_opt_get_string(ctx->opts, KRB5_BACKUP_KDC);
97 :
98 0 : use_kdcinfo = dp_opt_get_bool(ctx->opts, KRB5_USE_KDCINFO);
99 :
100 0 : ret = krb5_service_init(ctx, be_ctx, SSS_KRB5KDC_FO_SRV,
101 : primary_servers, backup_servers, realm,
102 : use_kdcinfo, &ctx->service);
103 0 : if (ret != EOK) {
104 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Failed to init KRB5 failover service!\n");
105 0 : return ret;
106 : }
107 :
108 0 : return EOK;
109 : }
110 :
111 0 : int krb5_ctx_re_destructor(struct krb5_ctx *ctx)
112 : {
113 0 : if (ctx->illegal_path_re != NULL) {
114 0 : pcre_free(ctx->illegal_path_re);
115 0 : ctx->illegal_path_re = NULL;
116 : }
117 :
118 0 : return 0;
119 : }
120 :
121 0 : errno_t sssm_krb5_init(TALLOC_CTX *mem_ctx,
122 : struct be_ctx *be_ctx,
123 : struct data_provider *provider,
124 : const char *module_name,
125 : void **_module_data)
126 : {
127 : struct krb5_ctx *ctx;
128 : const char *errstr;
129 : int errval;
130 : int errpos;
131 : errno_t ret;
132 :
133 0 : ctx = talloc_zero(mem_ctx, struct krb5_ctx);
134 0 : if (ctx == NULL) {
135 0 : DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero() failed\n");
136 0 : return ENOMEM;
137 : }
138 :
139 0 : ret = krb5_get_options(ctx, be_ctx->cdb, be_ctx->conf_path, &ctx->opts);
140 0 : if (ret != EOK) {
141 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get krb5 options [%d]: %s\n",
142 : ret, sss_strerror(ret));
143 0 : goto done;
144 : }
145 :
146 0 : ctx->action = INIT_PW;
147 0 : ctx->config_type = K5C_GENERIC;
148 :
149 0 : ret = krb5_init_kdc(ctx, be_ctx);
150 0 : if (ret != EOK) {
151 0 : goto done;
152 : }
153 :
154 0 : ret = krb5_init_kpasswd(ctx, be_ctx);
155 0 : if (ret != EOK) {
156 0 : goto done;
157 : }
158 :
159 0 : ret = krb5_child_init(ctx, be_ctx);
160 0 : if (ret != EOK) {
161 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Could not initialize krb5_child settings "
162 : "[%d]: %s\n", ret, sss_strerror(ret));
163 0 : goto done;
164 : }
165 :
166 0 : ctx->illegal_path_re = pcre_compile2(ILLEGAL_PATH_PATTERN, 0,
167 : &errval, &errstr, &errpos, NULL);
168 0 : if (ctx->illegal_path_re == NULL) {
169 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Invalid Regular Expression pattern "
170 : "at position %d. (Error: %d [%s])\n", errpos, errval, errstr);
171 0 : ret = EFAULT;
172 0 : goto done;
173 : }
174 0 : talloc_set_destructor(ctx, krb5_ctx_re_destructor);
175 :
176 0 : ret = be_fo_set_dns_srv_lookup_plugin(be_ctx, NULL);
177 0 : if (ret != EOK) {
178 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set SRV lookup plugin "
179 : "[%d]: %s\n", ret, sss_strerror(ret));
180 0 : goto done;
181 : }
182 :
183 0 : *_module_data = ctx;
184 :
185 0 : ret = EOK;
186 :
187 : done:
188 0 : if (ret != EOK) {
189 0 : talloc_free(ctx);
190 : }
191 :
192 0 : return ret;
193 : }
194 :
195 0 : errno_t sssm_krb5_auth_init(TALLOC_CTX *mem_ctx,
196 : struct be_ctx *be_ctx,
197 : void *module_data,
198 : struct dp_method *dp_methods)
199 : {
200 : struct krb5_ctx *ctx;
201 :
202 0 : ctx = talloc_get_type(module_data, struct krb5_ctx);
203 0 : dp_set_method(dp_methods, DPM_AUTH_HANDLER,
204 : krb5_pam_handler_send, krb5_pam_handler_recv, ctx,
205 : struct krb5_ctx, struct pam_data, struct pam_data *);
206 :
207 0 : return EOK;
208 : }
209 :
210 0 : errno_t sssm_krb5_chpass_init(TALLOC_CTX *mem_ctx,
211 : struct be_ctx *be_ctx,
212 : void *module_data,
213 : struct dp_method *dp_methods)
214 : {
215 0 : return sssm_krb5_auth_init(mem_ctx, be_ctx, module_data, dp_methods);
216 : }
217 :
218 0 : errno_t sssm_krb5_access_init(TALLOC_CTX *mem_ctx,
219 : struct be_ctx *be_ctx,
220 : void *module_data,
221 : struct dp_method *dp_methods)
222 : {
223 : struct krb5_ctx *ctx;
224 :
225 0 : ctx = talloc_get_type(module_data, struct krb5_ctx);
226 0 : dp_set_method(dp_methods, DPM_ACCESS_HANDLER,
227 : krb5_pam_handler_send, krb5_pam_handler_recv, ctx,
228 : struct krb5_ctx, struct pam_data, struct pam_data *);
229 :
230 0 : return EOK;
231 : }
|