2 Unix SMB/CIFS implementation.
3 IPA helper functions for SAMBA
4 Copyright (C) Sumit Bose <sbose@redhat.com> 2010
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #define LDAP_TRUST_CONTAINER "ou=system"
26 #define LDAP_ATTRIBUTE_CN "cn"
27 #define LDAP_ATTRIBUTE_TRUST_TYPE "sambaTrustType"
28 #define LDAP_ATTRIBUTE_TRUST_ATTRIBUTES "sambaTrustAttributes"
29 #define LDAP_ATTRIBUTE_TRUST_DIRECTION "sambaTrustDirection"
30 #define LDAP_ATTRIBUTE_TRUST_PARTNER "sambaTrustPartner"
31 #define LDAP_ATTRIBUTE_FLAT_NAME "sambaFlatName"
32 #define LDAP_ATTRIBUTE_TRUST_AUTH_OUTGOING "sambaTrustAuthOutgoing"
33 #define LDAP_ATTRIBUTE_TRUST_AUTH_INCOMING "sambaTrustAuthIncoming"
34 #define LDAP_ATTRIBUTE_SECURITY_IDENTIFIER "sambaSecurityIdentifier"
36 static bool ipasam_get_trusteddom_pw(struct pdb_methods
*methods
,
40 time_t *pass_last_set_time
)
45 static bool ipasam_set_trusteddom_pw(struct pdb_methods
*methods
,
48 const struct dom_sid
*sid
)
53 static bool ipasam_del_trusteddom_pw(struct pdb_methods
*methods
,
59 static NTSTATUS
ipasam_enum_trusteddoms(struct pdb_methods
*methods
,
61 uint32_t *num_domains
,
62 struct trustdom_info
***domains
)
64 return NT_STATUS_NOT_IMPLEMENTED
;
67 static char *trusted_domain_dn(struct ldapsam_privates
*ldap_state
,
70 return talloc_asprintf(talloc_tos(), "%s=%s,%s,%s",
71 LDAP_ATTRIBUTE_CN
, domain
,
72 LDAP_TRUST_CONTAINER
, ldap_state
->domain_dn
);
75 static char *trusted_domain_base_dn(struct ldapsam_privates
*ldap_state
)
77 return talloc_asprintf(talloc_tos(), "%s,%s",
78 LDAP_TRUST_CONTAINER
, ldap_state
->domain_dn
);
81 static bool get_trusted_domain_int(struct ldapsam_privates
*ldap_state
,
83 const char *domain
, LDAPMessage
**entry
)
88 LDAPMessage
*result
= NULL
;
91 filter
= talloc_asprintf(talloc_tos(),
92 "(&(objectClass=%s)(|(sambaFlatName=%s)(cn=%s)(sambaTrustPartner=%s)))",
93 LDAP_OBJ_TRUSTED_DOMAIN
, domain
, domain
, domain
);
98 base_dn
= trusted_domain_base_dn(ldap_state
);
99 if (base_dn
== NULL
) {
104 rc
= smbldap_search(ldap_state
->smbldap_state
, base_dn
,
105 LDAP_SCOPE_SUBTREE
, filter
, NULL
, 0, &result
);
107 TALLOC_FREE(base_dn
);
109 if (result
!= NULL
) {
110 talloc_autofree_ldapmsg(mem_ctx
, result
);
113 if (rc
== LDAP_NO_SUCH_OBJECT
) {
118 if (rc
!= LDAP_SUCCESS
) {
122 num_result
= ldap_count_entries(priv2ld(ldap_state
), result
);
124 if (num_result
> 1) {
125 DEBUG(1, ("get_trusted_domain_int: more than one "
126 "%s object for domain '%s'?!\n",
127 LDAP_OBJ_TRUSTED_DOMAIN
, domain
));
131 if (num_result
== 0) {
132 DEBUG(1, ("get_trusted_domain_int: no "
133 "%s object for domain %s.\n",
134 LDAP_OBJ_TRUSTED_DOMAIN
, domain
));
137 *entry
= ldap_first_entry(priv2ld(ldap_state
), result
);
143 static bool get_uint32_t_from_ldap_msg(struct ldapsam_privates
*ldap_state
,
152 dummy
= smbldap_talloc_single_attribute(priv2ld(ldap_state
), entry
,
155 DEBUG(9, ("Attribute %s not present.\n", attr
));
160 l
= strtoul(dummy
, &endptr
, 10);
163 if (l
< 0 || l
> UINT32_MAX
|| *endptr
!= '\0') {
172 static void get_data_blob_from_ldap_msg(TALLOC_CTX
*mem_ctx
,
173 struct ldapsam_privates
*ldap_state
,
174 LDAPMessage
*entry
, const char *attr
,
180 dummy
= smbldap_talloc_single_attribute(priv2ld(ldap_state
), entry
, attr
,
183 DEBUG(9, ("Attribute %s not present.\n", attr
));
186 blob
= base64_decode_data_blob(dummy
);
187 if (blob
.length
== 0) {
190 _blob
->length
= blob
.length
;
191 _blob
->data
= talloc_steal(mem_ctx
, blob
.data
);
197 static bool fill_pdb_trusted_domain(TALLOC_CTX
*mem_ctx
,
198 struct ldapsam_privates
*ldap_state
,
200 struct pdb_trusted_domain
**_td
)
204 struct pdb_trusted_domain
*td
;
210 td
= talloc_zero(mem_ctx
, struct pdb_trusted_domain
);
215 /* All attributes are MAY */
217 dummy
= smbldap_talloc_single_attribute(priv2ld(ldap_state
), entry
,
218 LDAP_ATTRIBUTE_SECURITY_IDENTIFIER
,
221 DEBUG(9, ("Attribute %s not present.\n",
222 LDAP_ATTRIBUTE_SECURITY_IDENTIFIER
));
223 ZERO_STRUCT(td
->security_identifier
);
225 res
= string_to_sid(&td
->security_identifier
, dummy
);
232 get_data_blob_from_ldap_msg(td
, ldap_state
, entry
,
233 LDAP_ATTRIBUTE_TRUST_AUTH_INCOMING
,
234 &td
->trust_auth_incoming
);
236 get_data_blob_from_ldap_msg(td
, ldap_state
, entry
,
237 LDAP_ATTRIBUTE_TRUST_AUTH_OUTGOING
,
238 &td
->trust_auth_outgoing
);
240 td
->netbios_name
= smbldap_talloc_single_attribute(priv2ld(ldap_state
),
242 LDAP_ATTRIBUTE_FLAT_NAME
,
244 if (td
->netbios_name
== NULL
) {
245 DEBUG(9, ("Attribute %s not present.\n",
246 LDAP_ATTRIBUTE_FLAT_NAME
));
249 td
->domain_name
= smbldap_talloc_single_attribute(priv2ld(ldap_state
),
251 LDAP_ATTRIBUTE_TRUST_PARTNER
,
253 if (td
->domain_name
== NULL
) {
254 DEBUG(9, ("Attribute %s not present.\n",
255 LDAP_ATTRIBUTE_TRUST_PARTNER
));
258 res
= get_uint32_t_from_ldap_msg(ldap_state
, entry
,
259 LDAP_ATTRIBUTE_TRUST_DIRECTION
,
260 &td
->trust_direction
);
265 res
= get_uint32_t_from_ldap_msg(ldap_state
, entry
,
266 LDAP_ATTRIBUTE_TRUST_ATTRIBUTES
,
267 &td
->trust_attributes
);
272 res
= get_uint32_t_from_ldap_msg(ldap_state
, entry
,
273 LDAP_ATTRIBUTE_TRUST_TYPE
,
284 static NTSTATUS
ipasam_get_trusted_domain(struct pdb_methods
*methods
,
287 struct pdb_trusted_domain
**td
)
289 struct ldapsam_privates
*ldap_state
=
290 (struct ldapsam_privates
*)methods
->private_data
;
291 LDAPMessage
*entry
= NULL
;
293 DEBUG(10, ("ipasam_get_trusted_domain called for domain %s\n", domain
));
295 if (!get_trusted_domain_int(ldap_state
, talloc_tos(), domain
, &entry
)) {
296 return NT_STATUS_UNSUCCESSFUL
;
299 DEBUG(5, ("ipasam_get_trusted_domain: no such trusted domain: "
301 return NT_STATUS_NO_SUCH_DOMAIN
;
304 if (!fill_pdb_trusted_domain(mem_ctx
, ldap_state
, entry
, td
)) {
305 return NT_STATUS_UNSUCCESSFUL
;
311 static bool smbldap_make_mod_uint32_t(LDAP
*ldap_struct
, LDAPMessage
*entry
,
312 LDAPMod
***mods
, const char *attribute
,
317 dummy
= talloc_asprintf(talloc_tos(), "%lu", (unsigned long) val
);
321 smbldap_make_mod(ldap_struct
, entry
, mods
, attribute
, dummy
);
327 static bool smbldap_make_mod_blob(LDAP
*ldap_struct
, LDAPMessage
*entry
,
328 LDAPMod
***mods
, const char *attribute
,
333 dummy
= base64_encode_data_blob(talloc_tos(), blob
);
338 smbldap_make_mod(ldap_struct
, entry
, mods
, attribute
, dummy
);
344 static NTSTATUS
ipasam_set_trusted_domain(struct pdb_methods
*methods
,
346 const struct pdb_trusted_domain
*td
)
348 struct ldapsam_privates
*ldap_state
=
349 (struct ldapsam_privates
*)methods
->private_data
;
350 LDAPMessage
*entry
= NULL
;
353 char *trusted_dn
= NULL
;
356 DEBUG(10, ("ipasam_set_trusted_domain called for domain %s\n", domain
));
358 res
= get_trusted_domain_int(ldap_state
, talloc_tos(), domain
, &entry
);
360 return NT_STATUS_UNSUCCESSFUL
;
364 smbldap_make_mod(priv2ld(ldap_state
), entry
, &mods
, "objectClass",
365 LDAP_OBJ_TRUSTED_DOMAIN
);
367 if (td
->netbios_name
!= NULL
) {
368 smbldap_make_mod(priv2ld(ldap_state
), entry
, &mods
,
369 LDAP_ATTRIBUTE_FLAT_NAME
,
373 if (td
->domain_name
!= NULL
) {
374 smbldap_make_mod(priv2ld(ldap_state
), entry
, &mods
,
375 LDAP_ATTRIBUTE_TRUST_PARTNER
,
379 if (!is_null_sid(&td
->security_identifier
)) {
380 smbldap_make_mod(priv2ld(ldap_state
), entry
, &mods
,
381 LDAP_ATTRIBUTE_SECURITY_IDENTIFIER
,
382 sid_string_tos(&td
->security_identifier
));
385 if (td
->trust_type
!= 0) {
386 res
= smbldap_make_mod_uint32_t(priv2ld(ldap_state
), entry
,
387 &mods
, LDAP_ATTRIBUTE_TRUST_TYPE
,
390 return NT_STATUS_UNSUCCESSFUL
;
394 if (td
->trust_attributes
!= 0) {
395 res
= smbldap_make_mod_uint32_t(priv2ld(ldap_state
), entry
,
397 LDAP_ATTRIBUTE_TRUST_ATTRIBUTES
,
398 td
->trust_attributes
);
400 return NT_STATUS_UNSUCCESSFUL
;
404 if (td
->trust_direction
!= 0) {
405 res
= smbldap_make_mod_uint32_t(priv2ld(ldap_state
), entry
,
407 LDAP_ATTRIBUTE_TRUST_DIRECTION
,
408 td
->trust_direction
);
410 return NT_STATUS_UNSUCCESSFUL
;
414 if (td
->trust_auth_outgoing
.data
!= NULL
) {
415 res
= smbldap_make_mod_blob(priv2ld(ldap_state
), entry
,
417 LDAP_ATTRIBUTE_TRUST_AUTH_OUTGOING
,
418 td
->trust_auth_outgoing
);
420 return NT_STATUS_UNSUCCESSFUL
;
424 if (td
->trust_auth_incoming
.data
!= NULL
) {
425 res
= smbldap_make_mod_blob(priv2ld(ldap_state
), entry
,
427 LDAP_ATTRIBUTE_TRUST_AUTH_INCOMING
,
428 td
->trust_auth_incoming
);
430 return NT_STATUS_UNSUCCESSFUL
;
434 talloc_autofree_ldapmod(talloc_tos(), mods
);
436 trusted_dn
= trusted_domain_dn(ldap_state
, domain
);
437 if (trusted_dn
== NULL
) {
438 return NT_STATUS_NO_MEMORY
;
441 ret
= smbldap_add(ldap_state
->smbldap_state
, trusted_dn
, mods
);
443 ret
= smbldap_modify(ldap_state
->smbldap_state
, trusted_dn
, mods
);
446 if (ret
!= LDAP_SUCCESS
) {
447 DEBUG(1, ("error writing trusted domain data!\n"));
448 return NT_STATUS_UNSUCCESSFUL
;
453 static NTSTATUS
ipasam_del_trusted_domain(struct pdb_methods
*methods
,
457 struct ldapsam_privates
*ldap_state
=
458 (struct ldapsam_privates
*)methods
->private_data
;
459 LDAPMessage
*entry
= NULL
;
462 if (!get_trusted_domain_int(ldap_state
, talloc_tos(), domain
, &entry
)) {
463 return NT_STATUS_UNSUCCESSFUL
;
467 DEBUG(5, ("ipasam_del_trusted_domain: no such trusted domain: "
469 return NT_STATUS_NO_SUCH_DOMAIN
;
472 dn
= smbldap_talloc_dn(talloc_tos(), priv2ld(ldap_state
), entry
);
474 DEBUG(0,("ipasam_del_trusted_domain: Out of memory!\n"));
475 return NT_STATUS_NO_MEMORY
;
478 ret
= smbldap_delete(ldap_state
->smbldap_state
, dn
);
479 if (ret
!= LDAP_SUCCESS
) {
480 return NT_STATUS_UNSUCCESSFUL
;
486 static NTSTATUS
ipasam_enum_trusted_domains(struct pdb_methods
*methods
,
488 uint32_t *num_domains
,
489 struct pdb_trusted_domain
***domains
)
492 struct ldapsam_privates
*ldap_state
=
493 (struct ldapsam_privates
*)methods
->private_data
;
494 char *base_dn
= NULL
;
496 int scope
= LDAP_SCOPE_SUBTREE
;
497 LDAPMessage
*result
= NULL
;
498 LDAPMessage
*entry
= NULL
;
500 filter
= talloc_asprintf(talloc_tos(), "(objectClass=%s)",
501 LDAP_OBJ_TRUSTED_DOMAIN
);
502 if (filter
== NULL
) {
503 return NT_STATUS_NO_MEMORY
;
506 base_dn
= trusted_domain_base_dn(ldap_state
);
507 if (base_dn
== NULL
) {
509 return NT_STATUS_NO_MEMORY
;
512 rc
= smbldap_search(ldap_state
->smbldap_state
, base_dn
, scope
, filter
,
515 TALLOC_FREE(base_dn
);
517 if (result
!= NULL
) {
518 talloc_autofree_ldapmsg(mem_ctx
, result
);
521 if (rc
== LDAP_NO_SUCH_OBJECT
) {
527 if (rc
!= LDAP_SUCCESS
) {
528 return NT_STATUS_UNSUCCESSFUL
;
532 if (!(*domains
= TALLOC_ARRAY(mem_ctx
, struct pdb_trusted_domain
*, 1))) {
533 DEBUG(1, ("talloc failed\n"));
534 return NT_STATUS_NO_MEMORY
;
537 for (entry
= ldap_first_entry(priv2ld(ldap_state
), result
);
539 entry
= ldap_next_entry(priv2ld(ldap_state
), entry
))
541 struct pdb_trusted_domain
*dom_info
;
543 if (!fill_pdb_trusted_domain(*domains
, ldap_state
, entry
,
545 return NT_STATUS_UNSUCCESSFUL
;
548 ADD_TO_ARRAY(*domains
, struct pdb_trusted_domain
*, dom_info
,
549 domains
, num_domains
);
551 if (*domains
== NULL
) {
552 DEBUG(1, ("talloc failed\n"));
553 return NT_STATUS_NO_MEMORY
;
557 DEBUG(5, ("ipasam_enum_trusted_domains: got %d domains\n", *num_domains
));
561 static NTSTATUS
pdb_init_IPA_ldapsam(struct pdb_methods
**pdb_method
, const char *location
)
563 struct ldapsam_privates
*ldap_state
;
565 NTSTATUS nt_status
= pdb_init_ldapsam(pdb_method
, location
);
567 (*pdb_method
)->name
= "IPA_ldapsam";
569 ldap_state
= (struct ldapsam_privates
*)((*pdb_method
)->private_data
);
570 ldap_state
->is_ipa_ldap
= true;
572 (*pdb_method
)->get_trusteddom_pw
= ipasam_get_trusteddom_pw
;
573 (*pdb_method
)->set_trusteddom_pw
= ipasam_set_trusteddom_pw
;
574 (*pdb_method
)->del_trusteddom_pw
= ipasam_del_trusteddom_pw
;
575 (*pdb_method
)->enum_trusteddoms
= ipasam_enum_trusteddoms
;
577 (*pdb_method
)->get_trusted_domain
= ipasam_get_trusted_domain
;
578 (*pdb_method
)->set_trusted_domain
= ipasam_set_trusted_domain
;
579 (*pdb_method
)->del_trusted_domain
= ipasam_del_trusted_domain
;
580 (*pdb_method
)->enum_trusted_domains
= ipasam_enum_trusted_domains
;
585 NTSTATUS
pdb_ipa_init(void)
589 if (!NT_STATUS_IS_OK(nt_status
= smb_register_passdb(PASSDB_INTERFACE_VERSION
, "IPA_ldapsam", pdb_init_IPA_ldapsam
)))