Bug Summary

File:daemons/ipa-kdb/ipa_kdb_passwords.c
Warning:line 193, column 12
Passed-by-value struct argument contains uninitialized data (e.g., field: 'magic')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ipa_kdb_passwords.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=all -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/10.0.0 -D HAVE_CONFIG_H -I . -I ../.. -I . -I ../../util -D PREFIX="/usr/local" -D BINDIR="/usr/local/bin" -D LIBDIR="/usr/local/lib" -D LIBEXECDIR="/usr/local/libexec" -D DATADIR="/usr/local/share" -D LDAPIDIR="/run" -I /usr/include/samba-4.0 -D _GNU_SOURCE=1 -D HAVE_IMMEDIATE_STRUCTURES=1 -I /usr/include/nss3 -I /usr/include/nspr4 -I /usr/include/nspr4 -I /usr/include/nss3 -I /usr/include/nspr4 -D __STDC_WANT_LIB_EXT1__=1 -D _DEFAULT_SOURCE=1 -D _POSIX_C_SOURCE=200809L -D PIC -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/10.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir /home/heimes/redhat/freeipa/daemons/ipa-kdb -ferror-limit 19 -fmessage-length 0 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -analyzer-output=html -faddrsig -o /home/heimes/redhat/freeipa/report/2020-06-05-101548-295465-1 -x c ipa_kdb_passwords.c
1/*
2 * MIT Kerberos KDC database backend for FreeIPA
3 *
4 * Authors: Simo Sorce <ssorce@redhat.com>
5 *
6 * Copyright (C) 2011 Simo Sorce, Red Hat
7 * see file 'COPYING' for use and warranty information
8 *
9 * This program is free software you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#include "ipa_kdb.h"
24#include "ipa_pwd.h"
25#include <kadm5/kadm_err.h>
26
27static krb5_error_code ipapwd_error_to_kerr(krb5_context context,
28 enum ipapwd_error err)
29{
30 krb5_error_code kerr;
31
32 switch(err) {
18
Control jumps to 'case IPAPWD_POLICY_OK:' at line 33
33 case IPAPWD_POLICY_OK:
34 kerr = 0;
35 break;
19
Execution continues on line 61
36 case IPAPWD_POLICY_ACCOUNT_EXPIRED:
37 kerr = KADM5_BAD_PRINCIPAL(43787538L);
38 krb5_set_error_message(context, kerr, "Account expired");
39 break;
40 case IPAPWD_POLICY_PWD_TOO_YOUNG:
41 kerr = KADM5_PASS_TOOSOON(43787546L);
42 krb5_set_error_message(context, kerr, "Too soon to change password");
43 break;
44 case IPAPWD_POLICY_PWD_TOO_SHORT:
45 kerr = KADM5_PASS_Q_TOOSHORT(43787542L);
46 krb5_set_error_message(context, kerr, "Password is too short");
47 break;
48 case IPAPWD_POLICY_PWD_IN_HISTORY:
49 kerr = KADM5_PASS_REUSE(43787545L);
50 krb5_set_error_message(context, kerr, "Password reuse not permitted");
51 break;
52 case IPAPWD_POLICY_PWD_COMPLEXITY:
53 kerr = KADM5_PASS_Q_CLASS(43787543L);
54 krb5_set_error_message(context, kerr, "Password is too simple");
55 break;
56 default:
57 kerr = KADM5_PASS_Q_GENERIC(43787577L);
58 break;
59 }
60
61 return kerr;
20
Returning zero (loaded from 'kerr'), which participates in a condition later
62}
63
64static krb5_error_code ipadb_check_pw_policy(krb5_context context,
65 char *passwd,
66 krb5_db_entry *db_entry)
67{
68 krb5_error_code kerr;
69 struct ipadb_e_data *ied;
70 struct ipadb_context *ipactx;
71 int ret;
72
73 ipactx = ipadb_get_context(context);
74 if (!ipactx) {
7
Assuming 'ipactx' is non-null, which participates in a condition later
8
Taking false branch
75 return KRB5_KDB_DBNOTINITED(-1780008435L);
76 }
77
78 ied = (struct ipadb_e_data *)db_entry->e_data;
79 if (ied->magic != IPA_E_DATA_MAGIC0x0eda7a) {
9
Assuming field 'magic' is equal to IPA_E_DATA_MAGIC
10
Taking false branch
80 return EINVAL22;
81 }
82
83 if (strlen(passwd) > IPAPWD_PASSWORD_MAX_LEN1000) {
11
Assuming the condition is false
12
Taking false branch
84 krb5_set_error_message(context, E2BIG7, "%s",
85 ipapwd_password_max_len_errmsg);
86 return E2BIG7;
87 }
88
89 ied->passwd = strdup(passwd);
90 if (!ied->passwd) {
13
Assuming field 'passwd' is non-null, which participates in a condition later
14
Taking false branch
91 return ENOMEM12;
92 }
93
94 kerr = ipadb_get_ipapwd_policy(ipactx, ied->pw_policy_dn, &ied->pol);
95 if (kerr != 0) {
15
Assuming 'kerr' is equal to 0
16
Taking false branch
96 return kerr;
97 }
98 ret = ipapwd_check_policy(ied->pol, passwd, time(NULL((void*)0)),
99 db_entry->expiration,
100 db_entry->pw_expiration,
101 ied->last_pwd_change,
102 ied->pw_history);
103 return ipapwd_error_to_kerr(context, ret);
17
Calling 'ipapwd_error_to_kerr'
21
Returning from 'ipapwd_error_to_kerr'
22
Returning zero, which participates in a condition later
104}
105
106krb5_error_code ipadb_change_pwd(krb5_context context,
107 krb5_keyblock *master_key,
108 krb5_key_salt_tuple *ks_tuple,
109 int ks_tuple_count, char *passwd,
110 int new_kvno, krb5_boolean keepold,
111 krb5_db_entry *db_entry)
112{
113 krb5_error_code kerr;
114 krb5_data pwd;
1
'pwd' initialized here
115 struct ipadb_context *ipactx;
116 struct ipadb_e_data *ied;
117 krb5_key_salt_tuple *fks = NULL((void*)0);
118 int n_fks;
119 krb5_key_data *keys = NULL((void*)0);
120 int n_keys;
121 krb5_key_data *tdata;
122 int t_keys;
123 int old_kvno;
124 int ret;
125 int i;
126
127 ipactx = ipadb_get_context(context);
128 if (!ipactx) {
2
Assuming 'ipactx' is non-null
3
Taking false branch
129 return KRB5_KDB_DBNOTINITED(-1780008435L);
130 }
131
132 if (!db_entry->e_data) {
4
Assuming field 'e_data' is non-null
5
Taking false branch
133 if (!ipactx->override_restrictions) {
134 return EINVAL22;
135 } else {
136 /* kadmin is creating a new principal */
137 ied = calloc(1, sizeof(struct ipadb_e_data));
138 if (!ied) {
139 return ENOMEM12;
140 }
141 ied->magic = IPA_E_DATA_MAGIC0x0eda7a;
142 /* set the default policy on new entries */
143 ret = asprintf(&ied->pw_policy_dn,
144 "cn=global_policy,%s", ipactx->realm_base);
145 if (ret == -1) {
146 free(ied);
147 return ENOMEM12;
148 }
149 db_entry->e_data = (krb5_octet *)ied;
150 }
151 }
152
153 /* check pwd policy before doing any other work */
154 kerr = ipadb_check_pw_policy(context, passwd, db_entry);
6
Calling 'ipadb_check_pw_policy'
23
Returning from 'ipadb_check_pw_policy'
155 if (kerr
23.1
'kerr' is 0
) {
24
Taking false branch
156 return kerr;
157 }
158
159 old_kvno = krb5_db_get_key_data_kvno(context, db_entry->n_key_data,
160 db_entry->key_data);
161 if (old_kvno >= new_kvno) {
25
Assuming 'old_kvno' is < 'new_kvno'
26
Taking false branch
162 new_kvno = old_kvno + 1;
163 }
164
165 pwd.data = passwd;
166 pwd.length = strlen(passwd);
167
168 /* detect if kadmin is just passing along the default set */
169 if (ks_tuple_count == ipactx->n_supp_encs) {
27
Assuming 'ks_tuple_count' is not equal to field 'n_supp_encs'
28
Taking false branch
170 for (i = 0; i < ks_tuple_count; i++) {
171 if (ks_tuple[i].ks_enctype != ipactx->supp_encs[i].ks_enctype)
172 break;
173 if (ks_tuple[i].ks_salttype != ipactx->supp_encs[i].ks_salttype)
174 break;
175 }
176 if (i == ks_tuple_count) {
177 /* we got passed the default supported enctypes, replace with
178 * the actual default enctypes to use */
179 ks_tuple = ipactx->def_encs;
180 ks_tuple_count = ipactx->n_def_encs;
181 }
182 }
183
184 /* We further filter supported enctypes to restrict to the list
185 * we have in ldap */
186 kerr = filter_key_salt_tuples(context, ks_tuple, ks_tuple_count,
187 ipactx->supp_encs, ipactx->n_supp_encs,
188 &fks, &n_fks);
189 if (kerr) {
29
Assuming 'kerr' is 0
30
Taking false branch
190 return kerr;
191 }
192
193 kerr = ipa_krb5_generate_key_data(context, db_entry->princ,
31
Passed-by-value struct argument contains uninitialized data (e.g., field: 'magic')
194 pwd, new_kvno, master_key,
195 n_fks, fks, &n_keys, &keys);
196 free(fks);
197 if (kerr) {
198 return kerr;
199 }
200
201 if (keepold) {
202 /* need to add the new keys to the old list */
203 t_keys = db_entry->n_key_data;
204
205 tdata = realloc(db_entry->key_data,
206 sizeof(krb5_key_data) * (t_keys + n_keys));
207 if (!tdata) {
208 ipa_krb5_free_key_data(keys, n_keys);
209 return ENOMEM12;
210 }
211 db_entry->key_data = tdata;
212 db_entry->n_key_data = t_keys + n_keys;
213
214 for (i = 0; i < n_keys; i++) {
215 db_entry->key_data[t_keys + i] = keys[i];
216 }
217 free(keys);
218
219 } else {
220
221 ipa_krb5_free_key_data(db_entry->key_data, db_entry->n_key_data);
222 db_entry->key_data = keys;
223 db_entry->n_key_data = n_keys;
224 }
225
226 return 0;
227}
228
229/*
230 * Check who actually changed the password, if it is not 'self' then
231 * we need to expire it if it is a user principal.
232 */
233krb5_error_code ipadb_get_pwd_expiration(krb5_context context,
234 krb5_db_entry *entry,
235 struct ipadb_e_data *ied,
236 time_t *expire_time)
237{
238 krb5_error_code kerr;
239 krb5_timestamp mod_time = 0;
240 krb5_principal mod_princ = NULL((void*)0);
241 krb5_boolean truexp = true1;
242
243 if (ied->ipa_user) {
244 kerr = krb5_dbe_lookup_mod_princ_data(context, entry,
245 &mod_time, &mod_princ);
246 if (kerr) {
247 goto done;
248 }
249
250 /* If the mod principal is kadmind then we have to assume an actual
251 * password change for now. Apparently kadmind does not properly pass
252 * the actual user principal down when said user is performing a
253 * password change */
254 if (mod_princ->length == 1 &&
255 strcmp(mod_princ->data[0].data, "kadmind") != 0) {
256 truexp = krb5_principal_compare(context, mod_princ, entry->princ);
257 }
258 }
259
260 if (truexp) {
261 if (ied->pol) {
262 if (ied->pol->max_pwd_life) {
263 *expire_time = mod_time + ied->pol->max_pwd_life;
264 } else {
265 *expire_time = 0;
266 }
267 } else {
268 *expire_time = mod_time + IPAPWD_DEFAULT_PWDLIFE(90 * 24 *3600);
269 }
270 } else {
271 /* not 'self', so reset */
272 *expire_time = mod_time;
273 }
274
275 /* in the case of integer owerflow, set expiration to IPAPWD_END_OF_TIME */
276 if ((*expire_time) < 0 || (*expire_time) > IPAPWD_END_OF_TIME2145916800) {
277 *expire_time = IPAPWD_END_OF_TIME2145916800; // 1 Jan 2038, 00:00 GMT
278 }
279
280 kerr = 0;
281
282done:
283 krb5_free_principal(context, mod_princ);
284 return kerr;
285}