Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : ads (active directory) utility library
4 : Copyright (C) Andrew Tridgell 2001
5 : Copyright (C) Andrew Bartlett 2001
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "includes.h"
22 : #include "ads.h"
23 :
24 : /* return a ldap dn path from a string, given separators and field name
25 : caller must free
26 : */
27 575 : ADS_STATUS ads_build_path(const char *realm,
28 : const char *sep,
29 : const char *field,
30 : int reverse,
31 : char **_path)
32 : {
33 0 : char *p, *r;
34 575 : int numbits = 0;
35 0 : char *ret;
36 0 : int len;
37 0 : char *saveptr;
38 :
39 575 : *_path = NULL;
40 :
41 575 : r = SMB_STRDUP(realm);
42 575 : if (r == NULL) {
43 0 : return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
44 : }
45 :
46 13736 : for (p=r; *p; p++) {
47 13161 : if (strchr(sep, *p)) {
48 1685 : numbits++;
49 : }
50 : }
51 :
52 575 : len = (numbits+1)*(strlen(field)+1) + strlen(r) + 1;
53 :
54 575 : ret = (char *)SMB_MALLOC(len);
55 575 : if (!ret) {
56 0 : free(r);
57 0 : return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
58 : }
59 :
60 575 : if (strlcpy(ret,field, len) >= len) {
61 : /* Truncate ! */
62 0 : free(r);
63 0 : free(ret);
64 0 : return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
65 : }
66 575 : p=strtok_r(r, sep, &saveptr);
67 575 : if (p) {
68 575 : if (strlcat(ret, p, len) >= len) {
69 0 : free(r);
70 0 : free(ret);
71 0 : return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
72 : }
73 :
74 2260 : while ((p=strtok_r(NULL, sep, &saveptr)) != NULL) {
75 0 : int retval;
76 1685 : char *s = NULL;
77 1685 : if (reverse)
78 0 : retval = asprintf(&s, "%s%s,%s", field, p, ret);
79 : else
80 1685 : retval = asprintf(&s, "%s,%s%s", ret, field, p);
81 1685 : free(ret);
82 1685 : if (retval == -1) {
83 0 : free(r);
84 0 : return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
85 : }
86 1685 : ret = SMB_STRDUP(s);
87 1685 : free(s);
88 : }
89 : }
90 :
91 575 : free(r);
92 :
93 575 : *_path = ret;
94 :
95 575 : return ADS_ERROR_NT(NT_STATUS_OK);
96 : }
97 :
98 : /* return a dn of the form "dc=AA,dc=BB,dc=CC" from a
99 : realm of the form AA.BB.CC
100 : caller must free
101 : */
102 573 : ADS_STATUS ads_build_dn(const char *realm, TALLOC_CTX *mem_ctx, char **_dn)
103 : {
104 0 : ADS_STATUS status;
105 573 : char *dn = NULL;
106 :
107 573 : status = ads_build_path(realm, ".", "dc=", 0, &dn);
108 573 : if (!ADS_ERR_OK(status)) {
109 0 : SAFE_FREE(dn);
110 0 : return status;
111 : }
112 :
113 573 : *_dn = talloc_strdup(mem_ctx, dn);
114 573 : SAFE_FREE(dn);
115 573 : if (*_dn == NULL) {
116 0 : return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
117 : }
118 :
119 573 : return ADS_ERROR_NT(NT_STATUS_OK);
120 : }
121 :
122 : /* return a DNS name in the for aa.bb.cc from the DN
123 : "dc=AA,dc=BB,dc=CC". caller must free
124 : */
125 22 : char *ads_build_domain(const char *dn)
126 : {
127 22 : char *dnsdomain = NULL;
128 :
129 : /* result should always be shorter than the DN */
130 :
131 22 : if ( (dnsdomain = SMB_STRDUP( dn )) == NULL ) {
132 0 : DEBUG(0,("ads_build_domain: malloc() failed!\n"));
133 0 : return NULL;
134 : }
135 :
136 22 : if (!strlower_m( dnsdomain )) {
137 0 : SAFE_FREE(dnsdomain);
138 0 : return NULL;
139 : }
140 :
141 22 : all_string_sub( dnsdomain, "dc=", "", 0);
142 22 : all_string_sub( dnsdomain, ",", ".", 0 );
143 :
144 22 : return dnsdomain;
145 : }
146 :
147 606 : static int ads_destructor(ADS_STRUCT *ads)
148 : {
149 : #ifdef HAVE_LDAP
150 606 : ads_disconnect(ads);
151 : #endif
152 606 : return 0;
153 : }
154 :
155 : /*
156 : initialise a ADS_STRUCT, ready for some ads_ ops
157 : */
158 606 : ADS_STRUCT *ads_init(TALLOC_CTX *mem_ctx,
159 : const char *realm,
160 : const char *workgroup,
161 : const char *ldap_server,
162 : enum ads_sasl_state_e sasl_state)
163 : {
164 606 : ADS_STRUCT *ads = NULL;
165 0 : int wrap_flags;
166 :
167 606 : ads = talloc_zero(mem_ctx, ADS_STRUCT);
168 606 : if (ads == NULL) {
169 0 : return NULL;
170 : }
171 606 : talloc_set_destructor(ads, ads_destructor);
172 :
173 : #ifdef HAVE_LDAP
174 606 : ads_zero_ldap(ads);
175 : #endif
176 :
177 606 : ads->server.realm = talloc_strdup(ads, realm);
178 606 : if (realm != NULL && ads->server.realm == NULL) {
179 0 : DBG_WARNING("Out of memory\n");
180 0 : TALLOC_FREE(ads);
181 0 : return NULL;
182 : }
183 :
184 606 : ads->server.workgroup = talloc_strdup(ads, workgroup);
185 606 : if (workgroup != NULL && ads->server.workgroup == NULL) {
186 0 : DBG_WARNING("Out of memory\n");
187 0 : TALLOC_FREE(ads);
188 0 : return NULL;
189 : }
190 :
191 606 : ads->server.ldap_server = talloc_strdup(ads, ldap_server);
192 606 : if (ldap_server != NULL && ads->server.ldap_server == NULL) {
193 0 : DBG_WARNING("Out of memory\n");
194 0 : TALLOC_FREE(ads);
195 0 : return NULL;
196 : }
197 :
198 606 : wrap_flags = lp_client_ldap_sasl_wrapping();
199 606 : if (wrap_flags == -1) {
200 0 : wrap_flags = 0;
201 : }
202 :
203 606 : switch (sasl_state) {
204 458 : case ADS_SASL_PLAIN:
205 458 : break;
206 0 : case ADS_SASL_SIGN:
207 0 : wrap_flags |= ADS_AUTH_SASL_SIGN;
208 0 : break;
209 148 : case ADS_SASL_SEAL:
210 148 : wrap_flags |= ADS_AUTH_SASL_SEAL;
211 148 : break;
212 : }
213 :
214 606 : ads->auth.flags = wrap_flags;
215 :
216 : /* Start with the configured page size when the connection is new,
217 : * we will drop it by half we get a timeout. */
218 606 : ads->config.ldap_page_size = lp_ldap_page_size();
219 :
220 606 : return ads;
221 : }
222 :
223 : /****************************************************************
224 : ****************************************************************/
225 :
226 2 : bool ads_set_sasl_wrap_flags(ADS_STRUCT *ads, unsigned flags)
227 : {
228 0 : unsigned other_flags;
229 :
230 2 : if (!ads) {
231 0 : return false;
232 : }
233 :
234 2 : other_flags = ads->auth.flags & ~(ADS_AUTH_SASL_SIGN|ADS_AUTH_SASL_SEAL);
235 :
236 2 : ads->auth.flags = flags | other_flags;
237 :
238 2 : return true;
239 : }
|