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 :
34 : struct krb5_options {
35 : struct dp_option *opts;
36 : struct krb5_ctx *auth_ctx;
37 : };
38 :
39 : struct krb5_options *krb5_options = NULL;
40 :
41 : struct bet_ops krb5_auth_ops = {
42 : .handler = krb5_pam_handler,
43 : .finalize = NULL,
44 : };
45 :
46 0 : int krb5_ctx_re_destructor(void *memctx)
47 : {
48 0 : struct krb5_ctx *ctx = (struct krb5_ctx *) memctx;
49 :
50 0 : if (ctx->illegal_path_re) {
51 0 : pcre_free(ctx->illegal_path_re);
52 0 : ctx->illegal_path_re = NULL;
53 : }
54 0 : return 0;
55 : }
56 :
57 0 : int sssm_krb5_auth_init(struct be_ctx *bectx,
58 : struct bet_ops **ops,
59 : void **pvt_auth_data)
60 : {
61 0 : struct krb5_ctx *ctx = NULL;
62 : int ret;
63 : const char *krb5_servers;
64 : const char *krb5_backup_servers;
65 : const char *krb5_kpasswd_servers;
66 : const char *krb5_backup_kpasswd_servers;
67 : const char *krb5_realm;
68 : const char *errstr;
69 : int errval;
70 : int errpos;
71 :
72 0 : if (krb5_options == NULL) {
73 0 : krb5_options = talloc_zero(bectx, struct krb5_options);
74 0 : if (krb5_options == NULL) {
75 0 : DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n");
76 0 : return ENOMEM;
77 : }
78 0 : ret = krb5_get_options(krb5_options, bectx->cdb, bectx->conf_path,
79 0 : &krb5_options->opts);
80 0 : if (ret != EOK) {
81 0 : DEBUG(SSSDBG_CRIT_FAILURE, "krb5_get_options failed.\n");
82 0 : return ret;
83 : }
84 : }
85 :
86 0 : if (krb5_options->auth_ctx != NULL) {
87 0 : *ops = &krb5_auth_ops;
88 0 : *pvt_auth_data = krb5_options->auth_ctx;
89 0 : return EOK;
90 : }
91 :
92 0 : ctx = talloc_zero(bectx, struct krb5_ctx);
93 0 : if (!ctx) {
94 0 : DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n");
95 0 : return ENOMEM;
96 : }
97 0 : krb5_options->auth_ctx = ctx;
98 :
99 0 : ctx->action = INIT_PW;
100 0 : ctx->opts = krb5_options->opts;
101 0 : ctx->config_type = K5C_GENERIC;
102 :
103 0 : krb5_servers = dp_opt_get_string(ctx->opts, KRB5_KDC);
104 0 : krb5_backup_servers = dp_opt_get_string(ctx->opts, KRB5_BACKUP_KDC);
105 :
106 0 : krb5_realm = dp_opt_get_string(ctx->opts, KRB5_REALM);
107 0 : if (krb5_realm == NULL) {
108 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Missing krb5_realm option!\n");
109 0 : return EINVAL;
110 : }
111 :
112 0 : ret = krb5_service_init(ctx, bectx,
113 : SSS_KRB5KDC_FO_SRV, krb5_servers,
114 : krb5_backup_servers, krb5_realm,
115 0 : dp_opt_get_bool(krb5_options->opts,
116 : KRB5_USE_KDCINFO),
117 : &ctx->service);
118 0 : if (ret != EOK) {
119 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Failed to init KRB5 failover service!\n");
120 0 : return ret;
121 : }
122 :
123 0 : krb5_kpasswd_servers = dp_opt_get_string(ctx->opts, KRB5_KPASSWD);
124 0 : krb5_backup_kpasswd_servers = dp_opt_get_string(ctx->opts,
125 : KRB5_BACKUP_KPASSWD);
126 0 : if (krb5_kpasswd_servers == NULL && krb5_backup_kpasswd_servers != NULL) {
127 0 : DEBUG(SSSDBG_CONF_SETTINGS, "kpasswd server wasn't specified but "
128 : "backup kpasswd given. Using it as primary\n");
129 0 : krb5_kpasswd_servers = krb5_backup_kpasswd_servers;
130 0 : krb5_backup_kpasswd_servers = NULL;
131 : }
132 :
133 0 : if (krb5_kpasswd_servers == NULL && krb5_servers != NULL) {
134 0 : DEBUG(SSSDBG_FATAL_FAILURE,
135 : "Missing krb5_kpasswd option and KDC set explicitly, "
136 : "will use KDC for pasword change operations!\n");
137 0 : ctx->kpasswd_service = NULL;
138 : } else {
139 0 : ret = krb5_service_init(ctx, bectx,
140 : SSS_KRB5KPASSWD_FO_SRV, krb5_kpasswd_servers,
141 : krb5_backup_kpasswd_servers, krb5_realm,
142 0 : dp_opt_get_bool(krb5_options->opts,
143 : KRB5_USE_KDCINFO),
144 : &ctx->kpasswd_service);
145 0 : if (ret != EOK) {
146 0 : DEBUG(SSSDBG_FATAL_FAILURE,
147 : "Failed to init KRB5KPASSWD failover service!\n");
148 0 : return ret;
149 : }
150 : }
151 :
152 : /* Initialize features needed by the krb5_child */
153 0 : ret = krb5_child_init(ctx, bectx);
154 0 : if (ret != EOK) {
155 0 : DEBUG(SSSDBG_FATAL_FAILURE,
156 : "Could not initialize krb5_child settings: [%s]\n",
157 : strerror(ret));
158 0 : goto fail;
159 : }
160 :
161 0 : ctx->illegal_path_re = pcre_compile2(ILLEGAL_PATH_PATTERN, 0,
162 : &errval, &errstr, &errpos, NULL);
163 0 : if (ctx->illegal_path_re == NULL) {
164 0 : DEBUG(SSSDBG_CRIT_FAILURE,
165 : "Invalid Regular Expression pattern at position %d. "
166 : "(Error: %d [%s])\n", errpos, errval, errstr);
167 0 : ret = EFAULT;
168 0 : goto fail;
169 : }
170 0 : talloc_set_destructor((TALLOC_CTX *) ctx, krb5_ctx_re_destructor);
171 :
172 0 : *ops = &krb5_auth_ops;
173 0 : *pvt_auth_data = ctx;
174 0 : return EOK;
175 :
176 : fail:
177 0 : talloc_zfree(krb5_options->auth_ctx);
178 0 : return ret;
179 : }
180 :
181 0 : int sssm_krb5_chpass_init(struct be_ctx *bectx,
182 : struct bet_ops **ops,
183 : void **pvt_auth_data)
184 : {
185 0 : return sssm_krb5_auth_init(bectx, ops, pvt_auth_data);
186 : }
187 :
188 0 : int sssm_krb5_access_init(struct be_ctx *bectx,
189 : struct bet_ops **ops,
190 : void **pvt_auth_data)
191 : {
192 0 : return sssm_krb5_auth_init(bectx, ops, pvt_auth_data);
193 : }
|