2 Unix SMB/CIFS mplementation.
3 NDS LDAP helper functions for SAMBA
4 Copyright (C) Vince Brimhall 2004-2005
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 2 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, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 #define NMASLDAP_GET_LOGIN_CONFIG_REQUEST "2.16.840.1.113719.1.39.42.100.3"
31 #define NMASLDAP_GET_LOGIN_CONFIG_RESPONSE "2.16.840.1.113719.1.39.42.100.4"
32 #define NMASLDAP_SET_PASSWORD_REQUEST "2.16.840.1.113719.1.39.42.100.11"
33 #define NMASLDAP_SET_PASSWORD_RESPONSE "2.16.840.1.113719.1.39.42.100.12"
34 #define NMASLDAP_GET_PASSWORD_REQUEST "2.16.840.1.113719.1.39.42.100.13"
35 #define NMASLDAP_GET_PASSWORD_RESPONSE "2.16.840.1.113719.1.39.42.100.14"
37 #define NMAS_LDAP_EXT_VERSION 1
39 /**********************************************************************
40 Take the request BER value and input data items and BER encodes the
41 data into the BER value
42 **********************************************************************/
44 static int berEncodePasswordData(
45 struct berval
**requestBV
,
48 const char *password2
)
51 BerElement
*requestBer
= NULL
;
53 const char * utf8ObjPtr
= NULL
;
55 const char * utf8PwdPtr
= NULL
;
57 const char * utf8Pwd2Ptr
= NULL
;
61 /* Convert objectDN and tag strings from Unicode to UTF-8 */
62 utf8ObjSize
= strlen(objectDN
)+1;
63 utf8ObjPtr
= objectDN
;
67 utf8PwdSize
= strlen(password
)+1;
68 utf8PwdPtr
= password
;
71 if (password2
!= NULL
)
73 utf8Pwd2Size
= strlen(password2
)+1;
74 utf8Pwd2Ptr
= password2
;
77 /* Allocate a BerElement for the request parameters. */
78 if((requestBer
= ber_alloc()) == NULL
)
80 err
= LDAP_ENCODING_ERROR
;
84 if (password
!= NULL
&& password2
!= NULL
)
86 /* BER encode the NMAS Version, the objectDN, and the password */
87 rc
= ber_printf(requestBer
, "{iooo}", NMAS_LDAP_EXT_VERSION
, utf8ObjPtr
, utf8ObjSize
, utf8PwdPtr
, utf8PwdSize
, utf8Pwd2Ptr
, utf8Pwd2Size
);
89 else if (password
!= NULL
)
91 /* BER encode the NMAS Version, the objectDN, and the password */
92 rc
= ber_printf(requestBer
, "{ioo}", NMAS_LDAP_EXT_VERSION
, utf8ObjPtr
, utf8ObjSize
, utf8PwdPtr
, utf8PwdSize
);
96 /* BER encode the NMAS Version and the objectDN */
97 rc
= ber_printf(requestBer
, "{io}", NMAS_LDAP_EXT_VERSION
, utf8ObjPtr
, utf8ObjSize
);
102 err
= LDAP_ENCODING_ERROR
;
110 /* Convert the BER we just built to a berval that we'll send with the extended request. */
111 if(ber_flatten(requestBer
, requestBV
) == LBER_ERROR
)
113 err
= LDAP_ENCODING_ERROR
;
121 ber_free(requestBer
, 1);
127 /**********************************************************************
128 Take the request BER value and input data items and BER encodes the
129 data into the BER value
130 **********************************************************************/
132 static int berEncodeLoginData(
133 struct berval
**requestBV
,
135 unsigned int methodIDLen
,
136 unsigned int *methodID
,
142 BerElement
*requestBer
= NULL
;
145 unsigned int elemCnt
= methodIDLen
/ sizeof(unsigned int);
147 char *utf8ObjPtr
=NULL
;
150 char *utf8TagPtr
= NULL
;
153 utf8ObjPtr
= objectDN
;
154 utf8ObjSize
= strlen(utf8ObjPtr
)+1;
157 utf8TagSize
= strlen(utf8TagPtr
)+1;
159 /* Allocate a BerElement for the request parameters. */
160 if((requestBer
= ber_alloc()) == NULL
)
162 err
= LDAP_ENCODING_ERROR
;
166 /* BER encode the NMAS Version and the objectDN */
167 err
= (ber_printf(requestBer
, "{io", NMAS_LDAP_EXT_VERSION
, utf8ObjPtr
, utf8ObjSize
) < 0) ? LDAP_ENCODING_ERROR
: 0;
169 /* BER encode the MethodID Length and value */
172 err
= (ber_printf(requestBer
, "{i{", methodIDLen
) < 0) ? LDAP_ENCODING_ERROR
: 0;
175 for (i
= 0; !err
&& i
< elemCnt
; i
++)
177 err
= (ber_printf(requestBer
, "i", methodID
[i
]) < 0) ? LDAP_ENCODING_ERROR
: 0;
182 err
= (ber_printf(requestBer
, "}}", 0) < 0) ? LDAP_ENCODING_ERROR
: 0;
187 /* BER Encode the the tag and data */
188 err
= (ber_printf(requestBer
, "oio}", utf8TagPtr
, utf8TagSize
, putDataLen
, putData
, putDataLen
) < 0) ? LDAP_ENCODING_ERROR
: 0;
192 /* BER Encode the the tag */
193 err
= (ber_printf(requestBer
, "o}", utf8TagPtr
, utf8TagSize
) < 0) ? LDAP_ENCODING_ERROR
: 0;
201 /* Convert the BER we just built to a berval that we'll send with the extended request. */
202 if(ber_flatten(requestBer
, requestBV
) == LBER_ERROR
)
204 err
= LDAP_ENCODING_ERROR
;
212 ber_free(requestBer
, 1);
218 /**********************************************************************
219 Takes the reply BER Value and decodes the NMAS server version and
220 return code and if a non null retData buffer was supplied, tries to
221 decode the the return data and length
222 **********************************************************************/
224 static int berDecodeLoginData(
225 struct berval
*replyBV
,
231 BerElement
*replyBer
= NULL
;
232 char *retOctStr
= NULL
;
233 size_t retOctStrLen
= 0;
235 if((replyBer
= ber_init(replyBV
)) == NULL
)
237 err
= LDAP_OPERATIONS_ERROR
;
243 retOctStrLen
= *retDataLen
+ 1;
244 retOctStr
= SMB_MALLOC(retOctStrLen
);
247 err
= LDAP_OPERATIONS_ERROR
;
251 if(ber_scanf(replyBer
, "{iis}", serverVersion
, &err
, retOctStr
, &retOctStrLen
) != -1)
253 if (*retDataLen
>= retOctStrLen
)
255 memcpy(retData
, retOctStr
, retOctStrLen
);
259 err
= LDAP_NO_MEMORY
;
262 *retDataLen
= retOctStrLen
;
266 err
= LDAP_DECODING_ERROR
;
271 if(ber_scanf(replyBer
, "{ii}", serverVersion
, &err
) == -1)
275 err
= LDAP_DECODING_ERROR
;
284 ber_free(replyBer
, 1);
287 if (retOctStr
!= NULL
)
289 memset(retOctStr
, 0, retOctStrLen
);
296 /**********************************************************************
297 Retrieves data in the login configuration of the specified object
298 that is tagged with the specified methodID and tag.
299 **********************************************************************/
301 static int getLoginConfig(
304 unsigned int methodIDLen
,
305 unsigned int *methodID
,
311 struct berval
*requestBV
= NULL
;
312 char *replyOID
= NULL
;
313 struct berval
*replyBV
= NULL
;
314 int serverVersion
= 0;
316 /* Validate unicode parameters. */
317 if((strlen(objectDN
) == 0) || ld
== NULL
)
319 return LDAP_NO_SUCH_ATTRIBUTE
;
322 err
= berEncodeLoginData(&requestBV
, objectDN
, methodIDLen
, methodID
, tag
, 0, NULL
);
328 /* Call the ldap_extended_operation (synchronously) */
329 if((err
= ldap_extended_operation_s(ld
, NMASLDAP_GET_LOGIN_CONFIG_REQUEST
,
330 requestBV
, NULL
, NULL
, &replyOID
, &replyBV
)))
335 /* Make sure there is a return OID */
338 err
= LDAP_NOT_SUPPORTED
;
342 /* Is this what we were expecting to get back. */
343 if(strcmp(replyOID
, NMASLDAP_GET_LOGIN_CONFIG_RESPONSE
))
345 err
= LDAP_NOT_SUPPORTED
;
349 /* Do we have a good returned berval? */
352 /* No; returned berval means we experienced a rather drastic error. */
353 /* Return operations error. */
354 err
= LDAP_OPERATIONS_ERROR
;
358 err
= berDecodeLoginData(replyBV
, &serverVersion
, dataLen
, data
);
360 if(serverVersion
!= NMAS_LDAP_EXT_VERSION
)
362 err
= LDAP_OPERATIONS_ERROR
;
373 /* Free the return OID string if one was returned. */
376 ldap_memfree(replyOID
);
379 /* Free memory allocated while building the request ber and berval. */
382 ber_bvfree(requestBV
);
385 /* Return the appropriate error/success code. */
389 /**********************************************************************
390 Attempts to get the Simple Password
391 **********************************************************************/
393 static int nmasldap_get_simple_pwd(
400 unsigned int methodID
= 0;
401 unsigned int methodIDLen
= sizeof(methodID
);
402 char tag
[] = {'P','A','S','S','W','O','R','D',' ','H','A','S','H',0};
404 size_t pwdBufLen
, bufferLen
;
406 bufferLen
= pwdBufLen
= pwdLen
+2;
407 pwdBuf
= SMB_MALLOC(pwdBufLen
); /* digest and null */
410 return LDAP_NO_MEMORY
;
413 err
= getLoginConfig(ld
, objectDN
, methodIDLen
, &methodID
, tag
, &pwdBufLen
, pwdBuf
);
418 pwdBuf
[pwdBufLen
] = 0; /* null terminate */
422 case 1: /* cleartext password */
424 case 2: /* SHA1 HASH */
426 case 4: /* UNIXCrypt_ID */
427 case 8: /* SSHA_ID */
428 default: /* Unknown digest */
429 err
= LDAP_INAPPROPRIATE_AUTH
; /* only return clear text */
435 if (pwdLen
>= pwdBufLen
-1)
437 memcpy(pwd
, &pwdBuf
[1], pwdBufLen
-1); /* skip digest tag and include null */
441 err
= LDAP_NO_MEMORY
;
449 memset(pwdBuf
, 0, bufferLen
);
457 /**********************************************************************
458 Attempts to set the Universal Password
459 **********************************************************************/
461 static int nmasldap_set_password(
463 const char *objectDN
,
468 struct berval
*requestBV
= NULL
;
469 char *replyOID
= NULL
;
470 struct berval
*replyBV
= NULL
;
473 /* Validate char parameters. */
474 if(objectDN
== NULL
|| (strlen(objectDN
) == 0) || pwd
== NULL
|| ld
== NULL
)
476 return LDAP_NO_SUCH_ATTRIBUTE
;
479 err
= berEncodePasswordData(&requestBV
, objectDN
, pwd
, NULL
);
485 /* Call the ldap_extended_operation (synchronously) */
486 if((err
= ldap_extended_operation_s(ld
, NMASLDAP_SET_PASSWORD_REQUEST
, requestBV
, NULL
, NULL
, &replyOID
, &replyBV
)))
491 /* Make sure there is a return OID */
494 err
= LDAP_NOT_SUPPORTED
;
498 /* Is this what we were expecting to get back. */
499 if(strcmp(replyOID
, NMASLDAP_SET_PASSWORD_RESPONSE
))
501 err
= LDAP_NOT_SUPPORTED
;
505 /* Do we have a good returned berval? */
508 /* No; returned berval means we experienced a rather drastic error. */
509 /* Return operations error. */
510 err
= LDAP_OPERATIONS_ERROR
;
514 err
= berDecodeLoginData(replyBV
, &serverVersion
, NULL
, NULL
);
516 if(serverVersion
!= NMAS_LDAP_EXT_VERSION
)
518 err
= LDAP_OPERATIONS_ERROR
;
529 /* Free the return OID string if one was returned. */
532 ldap_memfree(replyOID
);
535 /* Free memory allocated while building the request ber and berval. */
538 ber_bvfree(requestBV
);
541 /* Return the appropriate error/success code. */
545 /**********************************************************************
546 Attempts to get the Universal Password
547 **********************************************************************/
549 static int nmasldap_get_password(
552 size_t *pwdSize
, /* in bytes */
557 struct berval
*requestBV
= NULL
;
558 char *replyOID
= NULL
;
559 struct berval
*replyBV
= NULL
;
562 size_t pwdBufLen
, bufferLen
;
564 /* Validate char parameters. */
565 if(objectDN
== NULL
|| (strlen(objectDN
) == 0) || pwdSize
== NULL
|| ld
== NULL
)
567 return LDAP_NO_SUCH_ATTRIBUTE
;
570 bufferLen
= pwdBufLen
= *pwdSize
;
571 pwdBuf
= SMB_MALLOC(pwdBufLen
+2);
574 return LDAP_NO_MEMORY
;
577 err
= berEncodePasswordData(&requestBV
, objectDN
, NULL
, NULL
);
583 /* Call the ldap_extended_operation (synchronously) */
584 if((err
= ldap_extended_operation_s(ld
, NMASLDAP_GET_PASSWORD_REQUEST
, requestBV
, NULL
, NULL
, &replyOID
, &replyBV
)))
589 /* Make sure there is a return OID */
592 err
= LDAP_NOT_SUPPORTED
;
596 /* Is this what we were expecting to get back. */
597 if(strcmp(replyOID
, NMASLDAP_GET_PASSWORD_RESPONSE
))
599 err
= LDAP_NOT_SUPPORTED
;
603 /* Do we have a good returned berval? */
606 /* No; returned berval means we experienced a rather drastic error. */
607 /* Return operations error. */
608 err
= LDAP_OPERATIONS_ERROR
;
612 err
= berDecodeLoginData(replyBV
, &serverVersion
, &pwdBufLen
, pwdBuf
);
614 if(serverVersion
!= NMAS_LDAP_EXT_VERSION
)
616 err
= LDAP_OPERATIONS_ERROR
;
620 if (!err
&& pwdBufLen
!= 0)
622 if (*pwdSize
>= pwdBufLen
+1 && pwd
!= NULL
)
624 memcpy(pwd
, pwdBuf
, pwdBufLen
);
625 pwd
[pwdBufLen
] = 0; /* add null termination */
627 *pwdSize
= pwdBufLen
; /* does not include null termination */
637 /* Free the return OID string if one was returned. */
640 ldap_memfree(replyOID
);
643 /* Free memory allocated while building the request ber and berval. */
646 ber_bvfree(requestBV
);
651 memset(pwdBuf
, 0, bufferLen
);
655 /* Return the appropriate error/success code. */
659 /**********************************************************************
660 Get the user's password from NDS.
661 *********************************************************************/
663 int pdb_nds_get_password(
664 struct smbldap_state
*ldap_state
,
669 LDAP
*ld
= ldap_state
->ldap_struct
;
672 rc
= nmasldap_get_password(ld
, object_dn
, pwd_len
, pwd
);
673 if (rc
== LDAP_SUCCESS
) {
674 #ifdef DEBUG_PASSWORD
675 DEBUG(100,("nmasldap_get_password returned %s for %s\n", pwd
, object_dn
));
677 DEBUG(5, ("NDS Universal Password retrieved for %s\n", object_dn
));
679 DEBUG(3, ("NDS Universal Password NOT retrieved for %s\n", object_dn
));
682 if (rc
!= LDAP_SUCCESS
) {
683 rc
= nmasldap_get_simple_pwd(ld
, object_dn
, *pwd_len
, pwd
);
684 if (rc
== LDAP_SUCCESS
) {
685 #ifdef DEBUG_PASSWORD
686 DEBUG(100,("nmasldap_get_simple_pwd returned %s for %s\n", pwd
, object_dn
));
688 DEBUG(5, ("NDS Simple Password retrieved for %s\n", object_dn
));
690 /* We couldn't get the password */
691 DEBUG(3, ("NDS Simple Password NOT retrieved for %s\n", object_dn
));
692 return LDAP_INVALID_CREDENTIALS
;
696 /* We got the password */
700 /**********************************************************************
701 Set the users NDS, Universal and Simple passwords.
702 ********************************************************************/
704 int pdb_nds_set_password(
705 struct smbldap_state
*ldap_state
,
709 LDAP
*ld
= ldap_state
->ldap_struct
;
711 LDAPMod
**tmpmods
= NULL
;
713 rc
= nmasldap_set_password(ld
, object_dn
, pwd
);
714 if (rc
== LDAP_SUCCESS
) {
715 DEBUG(5,("NDS Universal Password changed for user %s\n", object_dn
));
717 char *ld_error
= NULL
;
718 ldap_get_option(ld
, LDAP_OPT_ERROR_STRING
, &ld_error
);
720 /* This will fail if Universal Password is not enabled for the user's context */
721 DEBUG(3,("NDS Universal Password could not be changed for user %s: %s (%s)\n",
722 object_dn
, ldap_err2string(rc
), ld_error
?ld_error
:"unknown"));
726 /* Set eDirectory Password */
727 smbldap_set_mod(&tmpmods
, LDAP_MOD_REPLACE
, "userPassword", pwd
);
728 rc
= smbldap_modify(ldap_state
, object_dn
, tmpmods
);
733 /**********************************************************************
734 Allow ldap server to update internal login attempt counters by
735 performing a simple bind. If the samba authentication failed attempt
736 the bind with a bogus, randomly generated password to count the
737 failed attempt. If the bind fails even though samba authentication
738 succeeded, this would indicate that the user's account is disabled,
739 time restrictions are in place or some other password policy
741 *********************************************************************/
743 static NTSTATUS
pdb_nds_update_login_attempts(struct pdb_methods
*methods
,
744 SAM_ACCOUNT
*sam_acct
, BOOL success
)
746 struct ldapsam_privates
*ldap_state
;
748 if ((!methods
) || (!sam_acct
)) {
749 DEBUG(3,("pdb_nds_update_login_attempts: invalid parameter.\n"));
750 return NT_STATUS_MEMORY_NOT_ALLOCATED
;
753 ldap_state
= (struct ldapsam_privates
*)methods
->private_data
;
756 /* Attempt simple bind with user credentials to update eDirectory
760 LDAPMessage
*result
= NULL
;
761 LDAPMessage
*entry
= NULL
;
762 const char **attr_list
;
764 char clear_text_pw
[512];
765 const char *p
= NULL
;
769 char ldap_server
[256];
770 const char *username
= pdb_get_username(sam_acct
);
771 BOOL got_clear_text_pw
= False
;
773 DEBUG(5,("pdb_nds_update_login_attempts: %s login for %s\n",
774 success
? "Successful" : "Failed", username
));
776 result
= pdb_get_backend_private_data(sam_acct
, methods
);
778 attr_list
= get_userattr_list(ldap_state
->schema_ver
);
779 rc
= ldapsam_search_suffix_by_name(ldap_state
, username
, &result
, attr_list
);
780 free_attr_list( attr_list
);
781 if (rc
!= LDAP_SUCCESS
) {
782 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
784 pdb_set_backend_private_data(sam_acct
, result
, private_data_free_fn
, methods
, PDB_CHANGED
);
787 if (ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
) == 0) {
788 DEBUG(0, ("pdb_nds_update_login_attempts: No user to modify!\n"));
789 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
792 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
793 dn
= smbldap_get_dn(ldap_state
->smbldap_state
->ldap_struct
, entry
);
795 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
798 DEBUG(3, ("pdb_nds_update_login_attempts: username %s found dn '%s'\n", username
, dn
));
800 pwd_len
= sizeof(clear_text_pw
);
801 if (success
== True
) {
802 if (pdb_nds_get_password(ldap_state
->smbldap_state
, dn
, &pwd_len
, clear_text_pw
) == LDAP_SUCCESS
) {
803 /* Got clear text password. Use simple ldap bind */
804 got_clear_text_pw
= True
;
807 generate_random_buffer((unsigned char *)clear_text_pw
, 24);
808 clear_text_pw
[24] = '\0';
809 DEBUG(5,("pdb_nds_update_login_attempts: using random password %s\n", clear_text_pw
));
812 /* Parse the location string */
813 p
= ldap_state
->location
;
815 /* skip leading "URL:" (if any) */
816 if ( strnequal( p
, "URL:", 4 ) ) {
820 sscanf(p
, "%10[^:]://%254[^:/]:%d", protocol
, ldap_server
, &ldap_port
);
822 if (ldap_port
== 0) {
823 if (strequal(protocol
, "ldap")) {
824 ldap_port
= LDAP_PORT
;
825 } else if (strequal(protocol
, "ldaps")) {
826 ldap_port
= LDAPS_PORT
;
828 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol
));
832 ld
= ldap_init(ldap_server
, ldap_port
);
837 /* LDAP version 3 required for ldap_sasl */
838 if (ldap_get_option(ld
, LDAP_OPT_PROTOCOL_VERSION
, &version
) == LDAP_OPT_SUCCESS
) {
839 if (version
!= LDAP_VERSION3
) {
840 version
= LDAP_VERSION3
;
841 if (ldap_set_option (ld
, LDAP_OPT_PROTOCOL_VERSION
, &version
) == LDAP_OPT_SUCCESS
) {
842 DEBUG(4, ("pdb_nds_update_login_attempts: Set protocol version to LDAP_VERSION3\n"));
847 /* Turn on ssl if required */
848 if(strequal(protocol
, "ldaps")) {
849 int tls
= LDAP_OPT_X_TLS_HARD
;
850 if (ldap_set_option (ld
, LDAP_OPT_X_TLS
, &tls
) != LDAP_SUCCESS
) {
851 DEBUG(1, ("pdb_nds_update_login_attempts: Failed to setup a TLS session\n"));
853 DEBUG(4, ("pdb_nds_update_login_attempts: Activated TLS on session\n"));
858 if((success
!= True
) || (got_clear_text_pw
== True
)) {
859 /* Attempt simple bind with real or bogus password */
860 rc
= ldap_simple_bind_s(ld
, dn
, clear_text_pw
);
861 if (rc
== LDAP_SUCCESS
) {
862 DEBUG(5,("pdb_nds_update_login_attempts: ldap_simple_bind_s Successful for %s\n", username
));
863 ldap_unbind_ext(ld
, NULL
, NULL
);
865 NTSTATUS nt_status
= NT_STATUS_ACCOUNT_RESTRICTION
;
866 DEBUG(5,("pdb_nds_update_login_attempts: ldap_simple_bind_s Failed for %s\n", username
));
868 case LDAP_INVALID_CREDENTIALS
:
869 nt_status
= NT_STATUS_WRONG_PASSWORD
;
882 /**********************************************************************
883 Intitalise the parts of the pdb_context that are common to NDS_ldapsam modes
884 *********************************************************************/
886 static NTSTATUS
pdb_init_NDS_ldapsam_common(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
888 struct ldapsam_privates
*ldap_state
= (*pdb_method
)->private_data
;
890 /* Mark this as eDirectory ldap */
891 ldap_state
->is_nds_ldap
= True
;
893 /* Add pdb_nds specific method for updating login attempts. */
894 (*pdb_method
)->update_login_attempts
= pdb_nds_update_login_attempts
;
896 /* Save location for use in pdb_nds_update_login_attempts */
897 ldap_state
->location
= SMB_STRDUP(location
);
903 /**********************************************************************
904 Initialise the 'nds compat' mode for pdb_ldap
905 *********************************************************************/
907 static NTSTATUS
pdb_init_NDS_ldapsam_compat(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
909 NTSTATUS nt_status
= pdb_init_ldapsam_compat(pdb_context
, pdb_method
, location
);
911 (*pdb_method
)->name
= "NDS_ldapsam_compat";
913 pdb_init_NDS_ldapsam_common(pdb_context
, pdb_method
, location
);
919 /**********************************************************************
920 Initialise the 'nds' normal mode for pdb_ldap
921 *********************************************************************/
923 static NTSTATUS
pdb_init_NDS_ldapsam(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
925 NTSTATUS nt_status
= pdb_init_ldapsam(pdb_context
, pdb_method
, location
);
927 (*pdb_method
)->name
= "NDS_ldapsam";
929 pdb_init_NDS_ldapsam_common(pdb_context
, pdb_method
, location
);
934 NTSTATUS
pdb_nds_init(void)
937 if (!NT_STATUS_IS_OK(nt_status
= smb_register_passdb(PASSDB_INTERFACE_VERSION
, "NDS_ldapsam", pdb_init_NDS_ldapsam
)))
940 if (!NT_STATUS_IS_OK(nt_status
= smb_register_passdb(PASSDB_INTERFACE_VERSION
, "NDS_ldapsam_compat", pdb_init_NDS_ldapsam_compat
)))