1 /*
2  * adcli
3  *
4  * Copyright (C) 2012 Red Hat Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301 USA
20  *
21  * Author: Stef Walter <stefw@gnome.org>
22  */
23 
24 #ifndef ADPRIVATE_H_
25 #define ADPRIVATE_H_
26 
27 #include "adattrs.h"
28 #include "adconn.h"
29 
30 #include <stdarg.h>
31 #include <limits.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <stdint.h>
35 
36 #include <ldap.h>
37 
38 #ifndef HOST_NAME_MAX
39 #define HOST_NAME_MAX 255
40 #endif
41 
42 #ifdef HEIMDAL
43 #define MAX_KEYTAB_NAME_LEN	1100	/* This is, what Samba does */
44 #define krb5_free_string(ctx, string)	krb5_xfree(string)
45 #define krb5_free_keytab_entry_contents	krb5_kt_free_entry /* Samba as well */
46 #else
47 typedef krb5_data	krb5_salt;	/* MIT Kerberos does not have this */
48 #endif
49 
50 /* Utilities */
51 
52 #if !defined(__cplusplus) && (__GNUC__ > 2)
53 #define GNUC_PRINTF(x, y) __attribute__((__format__(__printf__, x, y)))
54 #define GNUC_WARN_UNUSED __attribute__((warn_unused_result))
55 #else
56 #define GNUC_PRINTF(x, y)
57 #define GNUC_WARN_UNUSED
58 #endif
59 
60 /* For detecting clang features */
61 #ifndef __has_feature
62 #define __has_feature(x) 0
63 #endif
64 
65 #ifndef CLANG_ANALYZER_NORETURN
66 #if __has_feature(attribute_analyzer_noreturn)
67 #define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
68 #else
69 #define CLANG_ANALYZER_NORETURN
70 #endif
71 #endif
72 
73 #define return_val_if_fail(x, v) \
74 	do { if (!(x)) { \
75 	     _adcli_precond_failed ("adcli: '%s' not true at %s\n", #x, __func__); \
76 	     return v; \
77 	} } while (0)
78 
79 #define return_unexpected_if_fail(x) \
80 	return_val_if_fail ((x), ADCLI_ERR_UNEXPECTED)
81 
82 #define return_if_fail(x) \
83 	do { if (!(x)) { \
84 	     _adcli_precond_failed ("adcli: '%s' not true at %s\n", #x, __func__); \
85 	     return; \
86 	} } while (0)
87 
88 #define return_if_reached() \
89 	do { \
90 	     _adcli_precond_failed ("adcli: shouldn't be reached at %s\n", __func__); \
91 	     return; \
92 	} while (0)
93 
94 #define return_val_if_reached(v) \
95 	do { \
96 	     _adcli_precond_failed ("adcli: shouldn't be reached at %s\n", __func__); \
97 	     return v; \
98 	} while (0)
99 
100 #define return_unexpected_if_reached() \
101 	return_val_if_reached (ADCLI_ERR_UNEXPECTED)
102 
103 void           _adcli_precond_failed         (const char *message,
104                                               ...) GNUC_PRINTF (1, 2)
105                                               CLANG_ANALYZER_NORETURN;
106 
107 void           _adcli_err                    (const char *format,
108                                              ...) GNUC_PRINTF(1, 2);
109 
110 void           _adcli_warn                   (const char *format,
111                                              ...) GNUC_PRINTF(1, 2);
112 
113 void           _adcli_info                   (const char *format,
114                                              ...) GNUC_PRINTF(1, 2);
115 
116 int            _adcli_strv_len               (char **strv);
117 
118 char **        _adcli_strv_add               (char **strv,
119                                               char *string,
120                                               int *length) GNUC_WARN_UNUSED;
121 
122 char **        _adcli_strv_add_unique        (char **strv,
123                                               char *string,
124                                               int *length,
125                                               bool case_sensitive) GNUC_WARN_UNUSED;
126 
127 void           _adcli_strv_remove_unsorted   (char **strv,
128                                               const char *string,
129                                               int *length);
130 
131 void           _adcli_strv_free              (char **strv);
132 
133 int            _adcli_strv_has               (char **strv,
134                                               const char *str);
135 
136 int            _adcli_strv_has_ex            (char **strv,
137                                               const char *str,
138                                               int (* compare) (const char *match, const char*value));
139 
140 char **        _adcli_strv_dup               (char **strv) GNUC_WARN_UNUSED;
141 
142 char *         _adcli_strv_join              (char **strv,
143                                               const char *delim);
144 
145 void           _adcli_str_up                 (char *str);
146 
147 void           _adcli_str_down               (char *str);
148 
149 int            _adcli_str_is_up              (const char *str);
150 
151 int            _adcli_str_has_prefix         (const char *str,
152 		                              const char *prefix);
153 
154 int            _adcli_str_has_suffix         (const char *str,
155 		                              const char *suffix);
156 
157 char *          _adcli_bin_sid_to_str        (const uint8_t *data,
158                                               size_t len);
159 
160 char *         _adcli_str_dupn               (const void *data,
161                                               size_t len);
162 
163 void           _adcli_str_set                (char **field,
164                                               const char *value);
165 
166 void           _adcli_strv_set               (char ***field,
167                                               const char **value);
168 
169 int            _adcli_password_free          (char *password);
170 
171 int            _adcli_write_all              (int fd,
172                                               const char *buf,
173                                               int len);
174 
175 /* Connection helpers */
176 
177 char *        _adcli_calc_reset_password     (const char *computer_name);
178 
179 char *        _adcli_calc_netbios_name       (const char *host_fqdn);
180 
181 krb5_error_code  _adcli_kinit_computer_creds      (adcli_conn *conn,
182                                                    const char *in_tkt_service,
183                                                    krb5_ccache ccache,
184                                                    krb5_creds *creds);
185 
186 krb5_error_code  _adcli_kinit_user_creds          (adcli_conn *conn,
187                                                    const char *in_tkt_service,
188                                                    krb5_ccache ccache,
189                                                    krb5_creds *creds);
190 
191 /* LDAP helpers */
192 
193 adcli_result  _adcli_ldap_handle_failure     (LDAP *ldap,
194                                               adcli_result defres,
195                                               const char *desc,
196                                               ...) GNUC_PRINTF(3, 4);
197 
198 char *         _adcli_ldap_parse_sid         (LDAP *ldap,
199                                               LDAPMessage *results,
200                                               const char *attr_name);
201 
202 char *        _adcli_ldap_parse_value        (LDAP *ldap,
203                                               LDAPMessage *results,
204                                               const char *attr_name);
205 
206 char **       _adcli_ldap_parse_values       (LDAP *ldap,
207                                               LDAPMessage *results,
208                                               const char *attr_name);
209 
210 char *        _adcli_ldap_parse_dn           (LDAP *ldap,
211                                               LDAPMessage *results);
212 
213 int           _adcli_ldap_ber_case_equal     (struct berval *one,
214                                               struct berval *two);
215 
216 int           _adcli_ldap_have_vals          (struct berval **want,
217                                               struct berval **have);
218 
219 int           _adcli_ldap_have_in_mod        (LDAPMod *want,
220                                               struct berval **have);
221 
222 char *        _adcli_ldap_escape_filter      (const char *value);
223 
224 int           _adcli_ldap_dn_has_ancestor    (const char *dn,
225                                               const char *ancestor);
226 
227 int           _adcli_ldap_mod_compar         (void *match,
228                                               void *mod);
229 
230 int           _adcli_ldap_filter_for_add     (void *unused,
231                                               void *mod);
232 
233 LDAPMod *     _adcli_ldap_mod_new            (int mod_op,
234                                               const char *type,
235                                               const char **values);
236 
237 LDAPMod *     _adcli_ldap_mod_new1           (int mod_op,
238                                               const char *type,
239                                               const char *value);
240 
241 void          _adcli_ldap_mod_free           (void *mod);
242 
243 char *        _adcli_ldap_mods_to_string     (LDAPMod **mods);
244 
245 /* KRB5 helpers */
246 
247 adcli_result     _adcli_krb5_init_context         (krb5_context *k5);
248 
249 adcli_result     _adcli_krb5_open_keytab          (krb5_context k5,
250                                                    const char *keytab_name,
251                                                    krb5_keytab *keytab);
252 
253 krb5_error_code  _adcli_krb5_build_principal      (krb5_context k5,
254                                                    const char *user,
255                                                    const char *realm,
256                                                    krb5_principal *principal);
257 
258 krb5_error_code  _adcli_krb5_keytab_clear         (krb5_context k5,
259                                                    krb5_keytab keytab,
260                                                    krb5_boolean (* match_func) (krb5_context,
261                                                                 krb5_keytab_entry *, void *),
262                                                    void *match_data);
263 
264 krb5_error_code  _adcli_krb5_keytab_clear_all     (krb5_context k5,
265                                                    krb5_keytab keytab);
266 
267 krb5_error_code  _adcli_krb5_keytab_enumerate     (krb5_context k5,
268                                                    krb5_keytab keytab,
269                                                    krb5_boolean (* match_func) (krb5_context,
270                                                                 krb5_keytab_entry *, void *),
271                                                    void *match_data);
272 
273 krb5_error_code  _adcli_krb5_keytab_add_entries   (krb5_context k5,
274                                                    krb5_keytab keytab,
275                                                    krb5_principal princpal,
276                                                    krb5_kvno kvno,
277                                                    krb5_data *password,
278                                                    krb5_enctype *enctypes,
279                                                    const krb5_salt *salt);
280 
281 krb5_error_code  _adcli_krb5_keytab_test_salt     (krb5_context k5,
282                                                    krb5_keytab scratch,
283                                                    krb5_principal principal,
284                                                    krb5_kvno kvno,
285                                                    krb5_data *password,
286                                                    krb5_enctype *enctypes,
287                                                    const krb5_salt *salt);
288 
289 krb5_error_code  _adcli_krb5_keytab_discover_salt (krb5_context k5,
290                                                    krb5_principal principal,
291                                                    krb5_kvno kvno,
292                                                    krb5_data *password,
293                                                    krb5_enctype *enctypes,
294                                                    const krb5_salt *salts,
295                                                    int *discovered);
296 
297 krb5_error_code  _adcli_krb5_w2k3_salt            (krb5_context k5,
298                                                    krb5_principal principal,
299                                                    const char *host_netbios,
300                                                    krb5_salt *salt);
301 
302 krb5_enctype *   _adcli_krb5_parse_enctypes       (const char *value);
303 
304 char *           _adcli_krb5_format_enctypes      (krb5_enctype *enctypes);
305 
306 krb5_error_code  _adcli_krb5_keytab_copy_entries  (krb5_context k5,
307                                                    krb5_keytab keytab,
308                                                    krb5_principal principal,
309                                                    krb5_kvno kvno,
310                                                    krb5_enctype *enctypes);
311 
312 struct _adcli_attrs {
313 	LDAPMod **mods;
314 	int len;
315 };
316 
317 bool             _adcli_check_nt_time_string_lifetime (const char *nt_time_string, unsigned int lifetime);
318 
319 adcli_result     _adcli_call_external_program     (const char *binary,
320                                                    char * const *argv,
321                                                    const char *stdin_data,
322                                                    uint8_t **stdout_data,
323                                                    size_t *stdout_data_len);
324 
325 #endif /* ADPRIVATE_H_ */
326