2001-09-26 00:21:21 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2001-09-26 00:21:21 +04:00
LDAP protocol helper functions for SAMBA
2002-09-25 19:19:00 +04:00
Copyright ( C ) Jean Fran <EFBFBD> ois Micouleau 1998
Copyright ( C ) Gerald Carter 2001
Copyright ( C ) Shahms King 2001
Copyright ( C ) Andrew Bartlett 2002
Copyright ( C ) Stefan ( metze ) Metzmacher 2002
2002-08-17 21:00:51 +04:00
2001-09-26 00:21:21 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2002-07-15 14:35:28 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_PASSDB
# ifdef HAVE_LDAP
2001-09-26 00:21:21 +04:00
/* TODO:
* persistent connections : if using NSS LDAP , many connections are made
* however , using only one within Samba would be nice
*
* Clean up SSL stuff , compile on OpenLDAP 1. x , 2. x , and Netscape SDK
*
* Other LDAP based login attributes : accountExpires , etc .
* ( should be the domain of Samba proper , but the sam_password / SAM_ACCOUNT
* structures don ' t have fields for some of these attributes )
*
* SSL is done , but can ' t get the certificate based authentication to work
* against on my test platform ( Linux 2.4 , OpenLDAP 2. x )
*/
/* NOTE: this will NOT work against an Active Directory server
* due to the fact that the two password fields cannot be retrieved
* from a server ; recommend using security = domain in this situation
* and / or winbind
*/
# include <lber.h>
# include <ldap.h>
# ifndef SAM_ACCOUNT
# define SAM_ACCOUNT struct sam_passwd
# endif
2002-03-02 13:16:28 +03:00
struct ldapsam_privates {
/* Former statics */
2001-09-26 00:21:21 +04:00
LDAP * ldap_struct ;
LDAPMessage * result ;
LDAPMessage * entry ;
2002-03-01 18:17:10 +03:00
int index ;
2002-03-02 13:16:28 +03:00
2002-11-02 06:47:48 +03:00
time_t last_ping ;
2002-03-02 13:16:28 +03:00
/* retrive-once info */
const char * uri ;
BOOL permit_non_unix_accounts ;
uint32 low_nua_rid ;
uint32 high_nua_rid ;
2002-08-17 21:00:51 +04:00
char * bind_dn ;
char * bind_secret ;
2001-09-26 00:21:21 +04:00
} ;
2002-11-02 06:47:48 +03:00
# define LDAPSAM_DONT_PING_TIME 10 /* ping only all 10 seconds */
2002-08-17 21:00:51 +04:00
static struct ldapsam_privates * static_ldap_state ;
2002-03-02 13:16:28 +03:00
static uint32 ldapsam_get_next_available_nua_rid ( struct ldapsam_privates * ldap_state ) ;
2001-09-26 00:21:21 +04:00
2002-03-02 13:16:28 +03:00
/*******************************************************************
find the ldap password
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-15 14:35:28 +04:00
static BOOL fetch_ldapsam_pw ( char * * dn , char * * pw )
2002-03-02 13:16:28 +03:00
{
2002-07-15 14:35:28 +04:00
char * key = NULL ;
2002-03-02 13:16:28 +03:00
size_t size ;
2002-07-15 14:35:28 +04:00
* dn = smb_xstrdup ( lp_ldap_admin_dn ( ) ) ;
2002-03-02 13:16:28 +03:00
2002-07-15 14:35:28 +04:00
if ( asprintf ( & key , " %s/%s " , SECRETS_LDAP_BIND_PW , * dn ) < 0 ) {
SAFE_FREE ( * dn ) ;
DEBUG ( 0 , ( " fetch_ldapsam_pw: asprintf failed! \n " ) ) ;
2002-03-02 13:16:28 +03:00
}
2002-07-15 14:35:28 +04:00
* pw = secrets_fetch ( key , & size ) ;
if ( ! size ) {
/* Upgrade 2.2 style entry */
char * p ;
char * old_style_key = strdup ( * dn ) ;
char * data ;
fstring old_style_pw ;
if ( ! old_style_key ) {
DEBUG ( 0 , ( " fetch_ldapsam_pw: strdup failed! \n " ) ) ;
return False ;
}
2002-03-02 13:16:28 +03:00
2002-07-15 14:35:28 +04:00
for ( p = old_style_key ; * p ; p + + )
if ( * p = = ' , ' ) * p = ' / ' ;
data = secrets_fetch ( old_style_key , & size ) ;
if ( ! size & & size < sizeof ( old_style_pw ) ) {
DEBUG ( 0 , ( " fetch_ldap_pw: neither ldap secret retrieved! \n " ) ) ;
SAFE_FREE ( old_style_key ) ;
SAFE_FREE ( * dn ) ;
return False ;
}
strncpy ( old_style_pw , data , size ) ;
old_style_pw [ size ] = 0 ;
SAFE_FREE ( data ) ;
if ( ! secrets_store_ldap_pw ( * dn , old_style_pw ) ) {
DEBUG ( 0 , ( " fetch_ldap_pw: ldap secret could not be upgraded! \n " ) ) ;
SAFE_FREE ( old_style_key ) ;
SAFE_FREE ( * dn ) ;
return False ;
}
if ( ! secrets_delete ( old_style_key ) ) {
DEBUG ( 0 , ( " fetch_ldap_pw: old ldap secret could not be deleted! \n " ) ) ;
}
SAFE_FREE ( old_style_key ) ;
* pw = smb_xstrdup ( old_style_pw ) ;
}
2002-03-02 13:16:28 +03:00
return True ;
}
2001-09-26 00:21:21 +04:00
2002-07-15 14:35:28 +04:00
static const char * attr [ ] = { " uid " , " pwdLastSet " , " logonTime " ,
" logoffTime " , " kickoffTime " , " cn " ,
" pwdCanChange " , " pwdMustChange " ,
" displayName " , " homeDrive " ,
" smbHome " , " scriptPath " ,
" profilePath " , " description " ,
" userWorkstations " , " rid " ,
" primaryGroupID " , " lmPassword " ,
" ntPassword " , " acctFlags " ,
2002-11-02 06:47:48 +03:00
" domain " , NULL } ;
2001-12-31 03:06:51 +03:00
2001-09-26 00:21:21 +04:00
/*******************************************************************
open a connection to the ldap server .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-02 06:47:48 +03:00
static int ldapsam_open_connection ( struct ldapsam_privates * ldap_state , LDAP * * ldap_struct )
2001-09-26 00:21:21 +04:00
{
2002-11-02 06:47:48 +03:00
int rc = LDAP_SUCCESS ;
2002-08-17 21:00:51 +04:00
int version ;
2002-11-02 06:47:48 +03:00
BOOL ldap_v3 = False ;
2002-08-17 21:00:51 +04:00
2002-03-02 13:16:28 +03:00
# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
DEBUG ( 10 , ( " ldapsam_open_connection: %s \n " , ldap_state - > uri ) ) ;
2002-11-02 06:47:48 +03:00
if ( ( rc = ldap_initialize ( ldap_struct , ldap_state - > uri ) ) ! = LDAP_SUCCESS ) {
DEBUG ( 0 , ( " ldap_initialize: %s \n " , ldap_err2string ( rc ) ) ) ;
return rc ;
2001-09-26 00:21:21 +04:00
}
2002-08-17 21:00:51 +04:00
2002-03-02 13:16:28 +03:00
# else
2001-09-26 00:21:21 +04:00
2002-03-02 13:16:28 +03:00
/* Parse the string manually */
2001-09-26 00:21:21 +04:00
{
2002-03-02 13:16:28 +03:00
int port = 0 ;
fstring protocol ;
fstring host ;
const char * p = ldap_state - > uri ;
SMB_ASSERT ( sizeof ( protocol ) > 10 & & sizeof ( host ) > 254 ) ;
/* skip leading "URL:" (if any) */
if ( strncasecmp ( p , " URL: " , 4 ) = = 0 ) {
p + = 4 ;
2001-09-26 00:21:21 +04:00
}
2002-11-02 06:47:48 +03:00
2002-03-02 13:16:28 +03:00
sscanf ( p , " %10[^:]://%254s[^:]:%d " , protocol , host , & port ) ;
if ( port = = 0 ) {
if ( strequal ( protocol , " ldap " ) ) {
port = LDAP_PORT ;
} else if ( strequal ( protocol , " ldaps " ) ) {
port = LDAPS_PORT ;
} else {
DEBUG ( 0 , ( " unrecognised protocol (%s)! \n " , protocol ) ) ;
2001-09-26 00:21:21 +04:00
}
2002-03-02 13:16:28 +03:00
}
2002-11-02 06:47:48 +03:00
2002-03-02 13:16:28 +03:00
if ( ( * ldap_struct = ldap_init ( host , port ) ) = = NULL ) {
DEBUG ( 0 , ( " ldap_init failed ! \n " ) ) ;
2002-11-02 06:47:48 +03:00
return LDAP_OPERATIONS_ERROR ;
2002-03-02 13:16:28 +03:00
}
2002-11-02 06:47:48 +03:00
if ( strequal ( protocol , " ldaps " ) ) {
# ifdef LDAP_OPT_X_TLS
int tls = LDAP_OPT_X_TLS_HARD ;
if ( ldap_set_option ( * ldap_struct , LDAP_OPT_X_TLS , & tls ) ! = LDAP_SUCCESS )
2001-09-26 00:21:21 +04:00
{
2002-11-02 06:47:48 +03:00
DEBUG ( 0 , ( " Failed to setup a TLS session \n " ) ) ;
2001-09-26 00:21:21 +04:00
}
2002-11-02 06:47:48 +03:00
DEBUG ( 3 , ( " LDAPS option set...! \n " ) ) ;
# else
DEBUG ( 0 , ( " ldap_open_connection: Secure connection not supported by LDAP client libraries! \n " ) ) ;
return LDAP_OPERATIONS_ERROR ;
# endif
2002-03-02 13:16:28 +03:00
}
2002-11-02 06:47:48 +03:00
}
# endif
2002-03-02 13:16:28 +03:00
2002-11-02 06:47:48 +03:00
if ( ldap_get_option ( * ldap_struct , LDAP_OPT_PROTOCOL_VERSION , & version ) = = LDAP_OPT_SUCCESS )
{
if ( version ! = LDAP_VERSION3 )
{
version = LDAP_VERSION3 ;
if ( ldap_set_option ( * ldap_struct , LDAP_OPT_PROTOCOL_VERSION , & version ) = = LDAP_OPT_SUCCESS ) {
ldap_v3 = True ;
2001-09-26 00:21:21 +04:00
}
2002-03-02 13:16:28 +03:00
} else {
2002-11-02 06:47:48 +03:00
ldap_v3 = True ;
2002-03-02 13:16:28 +03:00
}
2001-09-26 00:21:21 +04:00
}
2002-11-02 06:47:48 +03:00
if ( lp_ldap_ssl ( ) = = LDAP_SSL_START_TLS ) {
# ifdef LDAP_OPT_X_TLS
if ( ldap_v3 ) {
if ( ( rc = ldap_start_tls_s ( * ldap_struct , NULL , NULL ) ) ! = LDAP_SUCCESS )
{
DEBUG ( 0 , ( " Failed to issue the StartTLS instruction: %s \n " ,
ldap_err2string ( rc ) ) ) ;
return rc ;
}
DEBUG ( 3 , ( " StartTLS issued: using a TLS connection \n " ) ) ;
} else {
DEBUG ( 0 , ( " Need LDAPv3 for Start TLS \n " ) ) ;
return LDAP_OPERATIONS_ERROR ;
}
# else
DEBUG ( 0 , ( " ldap_open_connection: StartTLS not supported by LDAP client libraries! \n " ) ) ;
return LDAP_OPERATIONS_ERROR ;
2002-03-02 13:16:28 +03:00
# endif
2002-11-02 06:47:48 +03:00
}
2001-09-26 00:21:21 +04:00
DEBUG ( 2 , ( " ldap_open_connection: connection opened \n " ) ) ;
2002-11-02 06:47:48 +03:00
return rc ;
2001-09-26 00:21:21 +04:00
}
2002-07-15 14:35:28 +04:00
/*******************************************************************
2002-08-17 21:00:51 +04:00
a rebind function for authenticated referrals
This version takes a void * that we can shove useful stuff in : - )
2002-07-15 14:35:28 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-25 19:19:00 +04:00
# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
# else
2002-08-17 21:00:51 +04:00
static int rebindproc_with_state ( LDAP * ld , char * * whop , char * * credp ,
int * methodp , int freeit , void * arg )
2002-07-15 14:35:28 +04:00
{
2002-08-17 21:00:51 +04:00
struct ldapsam_privates * ldap_state = arg ;
2002-07-15 14:35:28 +04:00
/** @TODO Should we be doing something to check what servers we rebind to?
Could we get a referral to a machine that we don ' t want to give our
username and password to ? */
2002-08-17 21:00:51 +04:00
if ( freeit ) {
SAFE_FREE ( * whop ) ;
memset ( * credp , ' \0 ' , strlen ( * credp ) ) ;
SAFE_FREE ( * credp ) ;
} else {
2002-07-15 14:35:28 +04:00
DEBUG ( 5 , ( " ldap_connect_system: Rebinding as \" %s \" \n " ,
2002-08-17 21:00:51 +04:00
ldap_state - > bind_dn ) ) ;
2002-07-15 14:35:28 +04:00
2002-08-17 21:00:51 +04:00
* whop = strdup ( ldap_state - > bind_dn ) ;
if ( ! * whop ) {
return LDAP_NO_MEMORY ;
}
* credp = strdup ( ldap_state - > bind_secret ) ;
if ( ! * credp ) {
SAFE_FREE ( * whop ) ;
return LDAP_NO_MEMORY ;
}
* methodp = LDAP_AUTH_SIMPLE ;
2002-07-15 14:35:28 +04:00
}
return 0 ;
}
2002-09-25 19:19:00 +04:00
# endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
2002-07-15 14:35:28 +04:00
2002-08-17 21:00:51 +04:00
/*******************************************************************
a rebind function for authenticated referrals
This version takes a void * that we can shove useful stuff in : - )
and actually does the connection .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-25 19:19:00 +04:00
# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
2002-08-17 21:00:51 +04:00
static int rebindproc_connect_with_state ( LDAP * ldap_struct ,
LDAP_CONST char * url ,
ber_tag_t request ,
ber_int_t msgid , void * arg )
{
struct ldapsam_privates * ldap_state = arg ;
int rc ;
DEBUG ( 5 , ( " ldap_connect_system: Rebinding as \" %s \" \n " ,
ldap_state - > bind_dn ) ) ;
/** @TODO Should we be doing something to check what servers we rebind to?
Could we get a referral to a machine that we don ' t want to give our
username and password to ? */
rc = ldap_simple_bind_s ( ldap_struct , ldap_state - > bind_dn , ldap_state - > bind_secret ) ;
return rc ;
}
2002-09-25 19:19:00 +04:00
# endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
2002-08-17 21:00:51 +04:00
/*******************************************************************
Add a rebind function for authenticated referrals
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-25 19:19:00 +04:00
# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
# else
# if LDAP_SET_REBIND_PROC_ARGS == 2
2002-08-17 21:00:51 +04:00
static int rebindproc ( LDAP * ldap_struct , char * * whop , char * * credp ,
int * method , int freeit )
{
return rebindproc_with_state ( ldap_struct , whop , credp ,
method , freeit , static_ldap_state ) ;
}
2002-09-25 19:19:00 +04:00
# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
# endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
2002-08-17 21:00:51 +04:00
/*******************************************************************
a rebind function for authenticated referrals
this also does the connection , but no void * .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-25 19:19:00 +04:00
# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
# if LDAP_SET_REBIND_PROC_ARGS == 2
2002-08-17 21:00:51 +04:00
static int rebindproc_connect ( LDAP * ld , LDAP_CONST char * url , int request ,
ber_int_t msgid )
{
return rebindproc_connect_with_state ( ld , url , ( ber_tag_t ) request , msgid ,
static_ldap_state ) ;
}
2002-09-25 19:19:00 +04:00
# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
# endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
2002-08-17 21:00:51 +04:00
2001-09-26 00:21:21 +04:00
/*******************************************************************
connect to the ldap server under system privilege .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-02 06:47:48 +03:00
static int ldapsam_connect_system ( struct ldapsam_privates * ldap_state , LDAP * ldap_struct )
2001-09-26 00:21:21 +04:00
{
int rc ;
2002-07-15 14:35:28 +04:00
char * ldap_dn ;
char * ldap_secret ;
2001-09-26 00:21:21 +04:00
2002-08-17 21:00:51 +04:00
/* The rebind proc needs this *HACK*. We are not multithreaded, so
this will work , but it ' s not nice . */
static_ldap_state = ldap_state ;
2002-07-15 14:35:28 +04:00
/* get the password */
if ( ! fetch_ldapsam_pw ( & ldap_dn , & ldap_secret ) )
2001-09-26 00:21:21 +04:00
{
2002-07-15 14:35:28 +04:00
DEBUG ( 0 , ( " ldap_connect_system: Failed to retrieve password from secrets.tdb \n " ) ) ;
2002-11-02 06:47:48 +03:00
return LDAP_INVALID_CREDENTIALS ;
2001-09-26 00:21:21 +04:00
}
2002-08-17 21:00:51 +04:00
ldap_state - > bind_dn = ldap_dn ;
ldap_state - > bind_secret = ldap_secret ;
2001-09-26 00:21:21 +04:00
/* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
( OpenLDAP ) doesnt ' seem to support it */
2001-12-31 03:06:51 +03:00
DEBUG ( 10 , ( " ldap_connect_system: Binding to ldap server as \" %s \" \n " ,
2002-07-15 14:35:28 +04:00
ldap_dn ) ) ;
2002-08-17 21:00:51 +04:00
# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
# if LDAP_SET_REBIND_PROC_ARGS == 2
ldap_set_rebind_proc ( ldap_struct , & rebindproc_connect ) ;
# endif
# if LDAP_SET_REBIND_PROC_ARGS == 3
ldap_set_rebind_proc ( ldap_struct , & rebindproc_connect_with_state , ( void * ) ldap_state ) ;
# endif
2002-09-25 19:19:00 +04:00
# else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
2002-08-17 21:00:51 +04:00
# if LDAP_SET_REBIND_PROC_ARGS == 2
ldap_set_rebind_proc ( ldap_struct , & rebindproc ) ;
# endif
# if LDAP_SET_REBIND_PROC_ARGS == 3
ldap_set_rebind_proc ( ldap_struct , & rebindproc_with_state , ( void * ) ldap_state ) ;
# endif
2002-09-25 19:19:00 +04:00
# endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
2002-07-15 14:35:28 +04:00
rc = ldap_simple_bind_s ( ldap_struct , ldap_dn , ldap_secret ) ;
2002-09-25 19:19:00 +04:00
if ( rc ! = LDAP_SUCCESS ) {
2001-09-26 00:21:21 +04:00
DEBUG ( 0 , ( " Bind failed: %s \n " , ldap_err2string ( rc ) ) ) ;
2002-11-02 06:47:48 +03:00
return rc ;
2001-09-26 00:21:21 +04:00
}
DEBUG ( 2 , ( " ldap_connect_system: succesful connection to the LDAP server \n " ) ) ;
2002-11-02 06:47:48 +03:00
return rc ;
}
/**********************************************************************
Connect to LDAP server
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int ldapsam_open ( struct ldapsam_privates * ldap_state )
{
int rc ;
SMB_ASSERT ( ldap_state ) ;
# ifndef NO_LDAP_SECURITY
if ( geteuid ( ) ! = 0 ) {
DEBUG ( 0 , ( " ldapsam_open: cannot access LDAP when not root.. \n " ) ) ;
return LDAP_INSUFFICIENT_ACCESS ;
}
# endif
if ( ( ldap_state - > ldap_struct ! = NULL ) & & ( ( ldap_state - > last_ping + LDAPSAM_DONT_PING_TIME ) < time ( NULL ) ) ) {
struct sockaddr_un addr ;
socklen_t len ;
int sd ;
if ( ldap_get_option ( ldap_state - > ldap_struct , LDAP_OPT_DESC , & sd ) = = 0 & &
getpeername ( sd , ( struct sockaddr * ) & addr , & len ) < 0 ) {
/* the other end has died. reopen. */
ldap_unbind_ext ( ldap_state - > ldap_struct , NULL , NULL ) ;
ldap_state - > ldap_struct = NULL ;
ldap_state - > last_ping = ( time_t ) 0 ;
} else {
ldap_state - > last_ping = time ( NULL ) ;
}
}
if ( ldap_state - > ldap_struct ! = NULL ) {
DEBUG ( 5 , ( " ldapsam_open: allready connected to the LDAP server \n " ) ) ;
return LDAP_SUCCESS ;
}
if ( ( rc = ldapsam_open_connection ( ldap_state , & ldap_state - > ldap_struct ) ) ) {
return rc ;
}
if ( ( rc = ldapsam_connect_system ( ldap_state , ldap_state - > ldap_struct ) ) ) {
ldap_unbind_ext ( ldap_state - > ldap_struct , NULL , NULL ) ;
ldap_state - > ldap_struct = NULL ;
return rc ;
}
ldap_state - > last_ping = time ( NULL ) ;
DEBUG ( 4 , ( " The LDAP server is succesful connected \n " ) ) ;
return LDAP_SUCCESS ;
}
/**********************************************************************
Disconnect from LDAP server
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS ldapsam_close ( struct ldapsam_privates * ldap_state )
{
if ( ! ldap_state )
return NT_STATUS_INVALID_PARAMETER ;
if ( ldap_state - > ldap_struct ! = NULL ) {
ldap_unbind_ext ( ldap_state - > ldap_struct , NULL , NULL ) ;
ldap_state - > ldap_struct = NULL ;
}
DEBUG ( 5 , ( " The connection to the LDAP server was closed \n " ) ) ;
/* maybe free the results here --metze */
return NT_STATUS_OK ;
}
static int ldapsam_retry_open ( struct ldapsam_privates * ldap_state , int * attempts )
{
int rc ;
SMB_ASSERT ( ldap_state & & attempts ) ;
if ( * attempts ! = 0 ) {
/* we retry after 0.5, 2, 4.5, 8, 12.5, 18, 24.5 seconds */
msleep ( ( ( ( * attempts ) * ( * attempts ) ) / 2 ) * 1000 ) ;
}
( * attempts ) + + ;
if ( ( rc = ldapsam_open ( ldap_state ) ) ) {
DEBUG ( 0 , ( " Connection to LDAP Server failed for the %d try! \n " , * attempts ) ) ;
return rc ;
}
return LDAP_SUCCESS ;
}
static int ldapsam_search ( struct ldapsam_privates * ldap_state , char * base , int scope , char * filter , char * attrs [ ] , int attrsonly , LDAPMessage * * res )
{
int rc = LDAP_SERVER_DOWN ;
int attempts = 0 ;
SMB_ASSERT ( ldap_state ) ;
while ( ( rc = = LDAP_SERVER_DOWN ) & & ( attempts < 8 ) ) {
if ( ( rc = ldapsam_retry_open ( ldap_state , & attempts ) ) ! = LDAP_SUCCESS )
continue ;
rc = ldap_search_s ( ldap_state - > ldap_struct , base , scope , filter , attrs , attrsonly , res ) ;
}
if ( rc = = LDAP_SERVER_DOWN ) {
DEBUG ( 0 , ( " %s: LDAP server is down! \n " , __FUNCTION__ ) ) ;
ldapsam_close ( ldap_state ) ;
}
return rc ;
}
static int ldapsam_modify ( struct ldapsam_privates * ldap_state , char * dn , LDAPMod * attrs [ ] )
{
int rc = LDAP_SERVER_DOWN ;
int attempts = 0 ;
if ( ! ldap_state )
return ( - 1 ) ;
while ( ( rc = = LDAP_SERVER_DOWN ) & & ( attempts < 8 ) ) {
if ( ( rc = ldapsam_retry_open ( ldap_state , & attempts ) ) ! = LDAP_SUCCESS )
continue ;
rc = ldap_modify_s ( ldap_state - > ldap_struct , dn , attrs ) ;
}
if ( rc = = LDAP_SERVER_DOWN ) {
DEBUG ( 0 , ( " %s: LDAP server is down! \n " , __FUNCTION__ ) ) ;
ldapsam_close ( ldap_state ) ;
}
return rc ;
}
static int ldapsam_add ( struct ldapsam_privates * ldap_state , const char * dn , LDAPMod * attrs [ ] )
{
int rc = LDAP_SERVER_DOWN ;
int attempts = 0 ;
if ( ! ldap_state )
return ( - 1 ) ;
while ( ( rc = = LDAP_SERVER_DOWN ) & & ( attempts < 8 ) ) {
if ( ( rc = ldapsam_retry_open ( ldap_state , & attempts ) ) ! = LDAP_SUCCESS )
continue ;
rc = ldap_add_s ( ldap_state - > ldap_struct , dn , attrs ) ;
}
if ( rc = = LDAP_SERVER_DOWN ) {
DEBUG ( 0 , ( " %s: LDAP server is down! \n " , __FUNCTION__ ) ) ;
ldapsam_close ( ldap_state ) ;
}
return rc ;
}
static int ldapsam_delete ( struct ldapsam_privates * ldap_state , char * dn )
{
int rc = LDAP_SERVER_DOWN ;
int attempts = 0 ;
if ( ! ldap_state )
return ( - 1 ) ;
while ( ( rc = = LDAP_SERVER_DOWN ) & & ( attempts < 8 ) ) {
if ( ( rc = ldapsam_retry_open ( ldap_state , & attempts ) ) ! = LDAP_SUCCESS )
continue ;
rc = ldap_delete_s ( ldap_state - > ldap_struct , dn ) ;
}
if ( rc = = LDAP_SERVER_DOWN ) {
DEBUG ( 0 , ( " %s: LDAP server is down! \n " , __FUNCTION__ ) ) ;
ldapsam_close ( ldap_state ) ;
}
return rc ;
}
static int ldapsam_extended_operation ( struct ldapsam_privates * ldap_state , LDAP_CONST char * reqoid , struct berval * reqdata , LDAPControl * * serverctrls , LDAPControl * * clientctrls , char * * retoidp , struct berval * * retdatap )
{
int rc = LDAP_SERVER_DOWN ;
int attempts = 0 ;
if ( ! ldap_state )
return ( - 1 ) ;
while ( ( rc = = LDAP_SERVER_DOWN ) & & ( attempts < 8 ) ) {
if ( ( rc = ldapsam_retry_open ( ldap_state , & attempts ) ) ! = LDAP_SUCCESS )
continue ;
rc = ldap_extended_operation_s ( ldap_state - > ldap_struct , reqoid , reqdata , serverctrls , clientctrls , retoidp , retdatap ) ;
}
if ( rc = = LDAP_SERVER_DOWN ) {
DEBUG ( 0 , ( " %s: LDAP server is down! \n " , __FUNCTION__ ) ) ;
ldapsam_close ( ldap_state ) ;
}
return rc ;
2001-09-26 00:21:21 +04:00
}
/*******************************************************************
run the search by name .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-02 06:47:48 +03:00
static int ldapsam_search_one_user ( struct ldapsam_privates * ldap_state , const char * filter , LDAPMessage * * result )
2001-09-26 00:21:21 +04:00
{
int scope = LDAP_SCOPE_SUBTREE ;
int rc ;
2002-03-02 13:16:28 +03:00
DEBUG ( 2 , ( " ldapsam_search_one_user: searching for:[%s] \n " , filter ) ) ;
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
rc = ldapsam_search ( ldap_state , lp_ldap_suffix ( ) , scope , ( char * ) filter , ( char * * ) attr , 0 , result ) ;
2001-09-26 00:21:21 +04:00
if ( rc ! = LDAP_SUCCESS ) {
2002-03-02 13:16:28 +03:00
DEBUG ( 0 , ( " ldapsam_search_one_user: Problem during the LDAP search: %s \n " ,
2001-09-26 00:21:21 +04:00
ldap_err2string ( rc ) ) ) ;
2002-03-02 13:16:28 +03:00
DEBUG ( 3 , ( " ldapsam_search_one_user: Query was: %s, %s \n " , lp_ldap_suffix ( ) ,
2001-09-26 00:21:21 +04:00
filter ) ) ;
}
2001-12-31 03:06:51 +03:00
return rc ;
2001-09-26 00:21:21 +04:00
}
/*******************************************************************
run the search by name .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-02 06:47:48 +03:00
static int ldapsam_search_one_user_by_name ( struct ldapsam_privates * ldap_state , const char * user ,
2001-09-26 00:21:21 +04:00
LDAPMessage * * result )
{
pstring filter ;
/*
2001-12-31 03:06:51 +03:00
* in the filter expression , replace % u with the real name
* so in ldap filter , % u MUST exist : - )
2001-09-26 00:21:21 +04:00
*/
pstrcpy ( filter , lp_ldap_filter ( ) ) ;
2001-12-31 03:06:51 +03:00
/*
* have to use this here because $ is filtered out
2001-09-26 00:21:21 +04:00
* in pstring_sub
*/
all_string_sub ( filter , " %u " , user , sizeof ( pstring ) ) ;
2002-11-02 06:47:48 +03:00
return ldapsam_search_one_user ( ldap_state , filter , result ) ;
2001-09-26 00:21:21 +04:00
}
/*******************************************************************
run the search by uid .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-02 13:16:28 +03:00
static int ldapsam_search_one_user_by_uid ( struct ldapsam_privates * ldap_state ,
2002-11-02 06:47:48 +03:00
int uid ,
2002-03-02 13:16:28 +03:00
LDAPMessage * * result )
2001-09-26 00:21:21 +04:00
{
struct passwd * user ;
pstring filter ;
/* Get the username from the system and look that up in the LDAP */
2001-12-31 03:06:51 +03:00
2002-03-02 13:16:28 +03:00
if ( ( user = getpwuid_alloc ( uid ) ) = = NULL ) {
DEBUG ( 3 , ( " ldapsam_search_one_user_by_uid: Failed to locate uid [%d] \n " , uid ) ) ;
2001-12-31 03:06:51 +03:00
return LDAP_NO_SUCH_OBJECT ;
}
2001-09-26 00:21:21 +04:00
pstrcpy ( filter , lp_ldap_filter ( ) ) ;
2001-12-31 03:06:51 +03:00
2001-09-26 00:21:21 +04:00
all_string_sub ( filter , " %u " , user - > pw_name , sizeof ( pstring ) ) ;
2002-03-02 13:16:28 +03:00
passwd_free ( & user ) ;
2002-11-02 06:47:48 +03:00
return ldapsam_search_one_user ( ldap_state , filter , result ) ;
2001-09-26 00:21:21 +04:00
}
/*******************************************************************
run the search by rid .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-02 13:16:28 +03:00
static int ldapsam_search_one_user_by_rid ( struct ldapsam_privates * ldap_state ,
2002-11-02 06:47:48 +03:00
uint32 rid ,
2002-03-02 13:16:28 +03:00
LDAPMessage * * result )
2001-09-26 00:21:21 +04:00
{
pstring filter ;
int rc ;
/* check if the user rid exsists, if not, try searching on the uid */
2001-12-31 03:06:51 +03:00
2001-09-26 00:21:21 +04:00
snprintf ( filter , sizeof ( filter ) - 1 , " rid=%i " , rid ) ;
2002-11-02 06:47:48 +03:00
rc = ldapsam_search_one_user ( ldap_state , filter , result ) ;
2001-09-26 00:21:21 +04:00
if ( rc ! = LDAP_SUCCESS )
2002-11-02 06:47:48 +03:00
rc = ldapsam_search_one_user_by_uid ( ldap_state ,
2002-07-15 14:35:28 +04:00
fallback_pdb_user_rid_to_uid ( rid ) ,
2002-03-02 13:16:28 +03:00
result ) ;
2001-09-26 00:21:21 +04:00
return rc ;
}
/*******************************************************************
search an attribute and return the first value found .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-12-31 03:06:51 +03:00
static BOOL get_single_attribute ( LDAP * ldap_struct , LDAPMessage * entry ,
2002-07-15 14:35:28 +04:00
char * attribute , pstring value )
2001-09-26 00:21:21 +04:00
{
2001-12-31 03:06:51 +03:00
char * * values ;
2001-09-26 00:21:21 +04:00
2001-12-31 03:06:51 +03:00
if ( ( values = ldap_get_values ( ldap_struct , entry , attribute ) ) = = NULL ) {
2001-09-26 00:21:21 +04:00
value = NULL ;
2002-03-02 13:16:28 +03:00
DEBUG ( 10 , ( " get_single_attribute: [%s] = [<does not exist>] \n " , attribute ) ) ;
2001-12-31 03:06:51 +03:00
return False ;
2001-09-26 00:21:21 +04:00
}
2002-03-02 13:16:28 +03:00
2001-12-31 03:06:51 +03:00
pstrcpy ( value , values [ 0 ] ) ;
ldap_value_free ( values ) ;
2002-03-02 13:16:28 +03:00
# ifdef DEBUG_PASSWORDS
DEBUG ( 100 , ( " get_single_attribute: [%s] = [%s] \n " , attribute , value ) ) ;
# endif
2001-12-31 03:06:51 +03:00
return True ;
2001-09-26 00:21:21 +04:00
}
/************************************************************************
Routine to manage the LDAPMod structure array
manage memory used by the array , by each struct , and values
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
This commit is number 4 of 4.
In particular this commit focuses on:
Actually adding the 'const' to the passdb interface, and the flow-on changes.
Also kill off the 'disp_info' stuff, as its no longer used.
While these changes have been mildly tested, and are pretty small, any
assistance in this is appreciated.
----
These changes introduces a large dose of 'const' to the Samba tree.
There are a number of good reasons to do this:
- I want to allow the SAM_ACCOUNT structure to move from wasteful
pstrings and fstrings to allocated strings. We can't do that if
people are modifying these outputs, as they may well make
assumptions about getting pstrings and fstrings
- I want --with-pam_smbpass to compile with a slightly sane
volume of warnings, currently its pretty bad, even in 2.2
where is compiles at all.
- Tridge assures me that he no longer opposes 'const religion'
based on the ability to #define const the problem away.
- Changed Get_Pwnam(x,y) into two variants (so that the const
parameter can work correctly): - Get_Pwnam(const x) and
Get_Pwnam_Modify(x).
- Reworked smbd/chgpasswd.c to work with these mods, passing
around a 'struct passwd' rather than the modified username
---
This finishes this line of commits off, your tree should now compile again :-)
Andrew Bartlett
(This used to be commit c95f5aeb9327347674589ae313b75bee3bf8e317)
2001-10-29 10:35:11 +03:00
static void make_a_mod ( LDAPMod * * * modlist , int modop , const char * attribute , const char * value )
2001-09-26 00:21:21 +04:00
{
LDAPMod * * mods ;
int i ;
int j ;
mods = * modlist ;
if ( attribute = = NULL | | * attribute = = ' \0 ' )
return ;
if ( value = = NULL | | * value = = ' \0 ' )
return ;
if ( mods = = NULL )
{
mods = ( LDAPMod * * ) malloc ( sizeof ( LDAPMod * ) ) ;
if ( mods = = NULL )
{
DEBUG ( 0 , ( " make_a_mod: out of memory! \n " ) ) ;
return ;
}
mods [ 0 ] = NULL ;
}
for ( i = 0 ; mods [ i ] ! = NULL ; + + i ) {
if ( mods [ i ] - > mod_op = = modop & & ! strcasecmp ( mods [ i ] - > mod_type , attribute ) )
break ;
}
if ( mods [ i ] = = NULL )
{
2001-12-31 03:06:51 +03:00
mods = ( LDAPMod * * ) Realloc ( mods , ( i + 2 ) * sizeof ( LDAPMod * ) ) ;
2001-09-26 00:21:21 +04:00
if ( mods = = NULL )
{
DEBUG ( 0 , ( " make_a_mod: out of memory! \n " ) ) ;
return ;
}
mods [ i ] = ( LDAPMod * ) malloc ( sizeof ( LDAPMod ) ) ;
if ( mods [ i ] = = NULL )
{
DEBUG ( 0 , ( " make_a_mod: out of memory! \n " ) ) ;
return ;
}
mods [ i ] - > mod_op = modop ;
mods [ i ] - > mod_values = NULL ;
mods [ i ] - > mod_type = strdup ( attribute ) ;
mods [ i + 1 ] = NULL ;
}
if ( value ! = NULL )
{
j = 0 ;
if ( mods [ i ] - > mod_values ! = NULL ) {
for ( ; mods [ i ] - > mod_values [ j ] ! = NULL ; j + + ) ;
}
2001-12-31 03:06:51 +03:00
mods [ i ] - > mod_values = ( char * * ) Realloc ( mods [ i ] - > mod_values ,
2001-09-26 00:21:21 +04:00
( j + 2 ) * sizeof ( char * ) ) ;
if ( mods [ i ] - > mod_values = = NULL ) {
DEBUG ( 0 , ( " make_a_mod: Memory allocation failure! \n " ) ) ;
return ;
}
mods [ i ] - > mod_values [ j ] = strdup ( value ) ;
mods [ i ] - > mod_values [ j + 1 ] = NULL ;
}
* modlist = mods ;
}
/* New Interface is being implemented here */
/**********************************************************************
Initialize SAM_ACCOUNT from an LDAP query
( Based on init_sam_from_buffer in pdb_tdb . c )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-02 13:16:28 +03:00
static BOOL init_sam_from_ldap ( struct ldapsam_privates * ldap_state ,
SAM_ACCOUNT * sampass ,
2002-11-02 06:47:48 +03:00
LDAPMessage * entry )
2001-09-26 00:21:21 +04:00
{
time_t logon_time ,
logoff_time ,
kickoff_time ,
pass_last_set_time ,
pass_can_change_time ,
pass_must_change_time ;
2001-12-31 03:06:51 +03:00
pstring username ,
domain ,
nt_username ,
fullname ,
homedir ,
dir_drive ,
logon_script ,
profile_path ,
acct_desc ,
munged_dial ,
workstations ;
2002-01-21 11:08:54 +03:00
struct passwd * pw ;
2001-12-31 03:06:51 +03:00
uint32 user_rid ,
group_rid ;
2002-11-02 06:47:48 +03:00
uint8 smblmpwd [ LM_HASH_LEN ] ,
smbntpwd [ NT_HASH_LEN ] ;
2001-12-31 03:06:51 +03:00
uint16 acct_ctrl ,
logon_divs ;
2001-09-26 00:21:21 +04:00
uint32 hours_len ;
2001-12-31 03:06:51 +03:00
uint8 hours [ MAX_HOURS_LEN ] ;
2001-09-26 00:21:21 +04:00
pstring temp ;
2002-01-21 11:08:54 +03:00
uid_t uid = - 1 ;
2001-12-31 03:06:51 +03:00
gid_t gid = getegid ( ) ;
/*
* do a little initialization
*/
username [ 0 ] = ' \0 ' ;
domain [ 0 ] = ' \0 ' ;
nt_username [ 0 ] = ' \0 ' ;
fullname [ 0 ] = ' \0 ' ;
homedir [ 0 ] = ' \0 ' ;
dir_drive [ 0 ] = ' \0 ' ;
logon_script [ 0 ] = ' \0 ' ;
profile_path [ 0 ] = ' \0 ' ;
acct_desc [ 0 ] = ' \0 ' ;
munged_dial [ 0 ] = ' \0 ' ;
workstations [ 0 ] = ' \0 ' ;
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
if ( sampass = = NULL | | ldap_state = = NULL | | entry = = NULL ) {
2001-12-30 22:21:25 +03:00
DEBUG ( 0 , ( " init_sam_from_ldap: NULL parameters found! \n " ) ) ;
return False ;
}
2002-11-02 06:47:48 +03:00
if ( ldap_state - > ldap_struct = = NULL ) {
DEBUG ( 0 , ( " init_sam_from_ldap: ldap_state->ldap_struct is NULL! \n " ) ) ;
return False ;
}
get_single_attribute ( ldap_state - > ldap_struct , entry , " uid " , username ) ;
2001-09-26 00:21:21 +04:00
DEBUG ( 2 , ( " Entry found for user: %s \n " , username ) ) ;
2001-10-10 21:04:23 +04:00
pstrcpy ( nt_username , username ) ;
2001-09-26 00:21:21 +04:00
2001-12-31 03:09:15 +03:00
pstrcpy ( domain , lp_workgroup ( ) ) ;
2002-11-02 06:47:48 +03:00
pdb_set_username ( sampass , username , PDB_SET ) ;
pdb_set_domain ( sampass , domain , PDB_DEFAULT ) ;
pdb_set_nt_username ( sampass , nt_username , PDB_SET ) ;
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
get_single_attribute ( ldap_state - > ldap_struct , entry , " rid " , temp ) ;
2002-03-02 13:16:28 +03:00
user_rid = ( uint32 ) atol ( temp ) ;
2002-07-15 14:35:28 +04:00
2002-11-02 06:47:48 +03:00
pdb_set_user_sid_from_rid ( sampass , user_rid , PDB_SET ) ;
2002-07-15 14:35:28 +04:00
2002-11-02 06:47:48 +03:00
if ( ! get_single_attribute ( ldap_state - > ldap_struct , entry , " primaryGroupID " , temp ) ) {
2002-03-02 13:16:28 +03:00
group_rid = 0 ;
} else {
group_rid = ( uint32 ) atol ( temp ) ;
2002-11-02 06:47:48 +03:00
pdb_set_group_sid_from_rid ( sampass , group_rid , PDB_SET ) ;
2002-03-02 13:16:28 +03:00
}
if ( ( ldap_state - > permit_non_unix_accounts )
& & ( user_rid > = ldap_state - > low_nua_rid )
& & ( user_rid < = ldap_state - > high_nua_rid ) ) {
} else {
/* These values MAY be in LDAP, but they can also be retrieved through
* sys_getpw * ( ) which is how we ' re doing it
*/
pw = getpwnam_alloc ( username ) ;
if ( pw = = NULL ) {
2002-07-15 14:35:28 +04:00
DEBUG ( 2 , ( " init_sam_from_ldap: User [%s] does not exist via system getpwnam! \n " , username ) ) ;
2002-03-02 13:16:28 +03:00
return False ;
}
uid = pw - > pw_uid ;
gid = pw - > pw_gid ;
2002-11-02 06:47:48 +03:00
pdb_set_unix_homedir ( sampass , pw - > pw_dir , PDB_SET ) ;
2002-07-15 14:35:28 +04:00
2002-03-02 13:16:28 +03:00
passwd_free ( & pw ) ;
2002-11-02 06:47:48 +03:00
pdb_set_uid ( sampass , uid , PDB_SET ) ;
pdb_set_gid ( sampass , gid , PDB_SET ) ;
2002-03-02 13:16:28 +03:00
if ( group_rid = = 0 ) {
GROUP_MAP map ;
/* call the mapping code here */
2002-11-02 06:47:48 +03:00
if ( pdb_getgrgid ( & map , gid , MAPPING_WITHOUT_PRIV ) ) {
pdb_set_group_sid ( sampass , & map . sid , PDB_SET ) ;
2002-03-02 13:16:28 +03:00
}
else {
2002-11-02 06:47:48 +03:00
pdb_set_group_sid_from_rid ( sampass , pdb_gid_to_group_rid ( gid ) , PDB_SET ) ;
2002-03-02 13:16:28 +03:00
}
}
}
2002-11-02 06:47:48 +03:00
if ( ! get_single_attribute ( ldap_state - > ldap_struct , entry , " pwdLastSet " , temp ) ) {
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
pass_last_set_time = ( time_t ) atol ( temp ) ;
2002-11-02 06:47:48 +03:00
pdb_set_pass_last_set_time ( sampass , pass_last_set_time , PDB_SET ) ;
2002-04-08 05:52:44 +04:00
}
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
if ( ! get_single_attribute ( ldap_state - > ldap_struct , entry , " logonTime " , temp ) ) {
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
2002-03-02 13:16:28 +03:00
logon_time = ( time_t ) atol ( temp ) ;
2002-11-02 06:47:48 +03:00
pdb_set_logon_time ( sampass , logon_time , PDB_SET ) ;
2002-03-02 13:16:28 +03:00
}
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
if ( ! get_single_attribute ( ldap_state - > ldap_struct , entry , " logoffTime " , temp ) ) {
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
2002-03-02 13:16:28 +03:00
logoff_time = ( time_t ) atol ( temp ) ;
2002-11-02 06:47:48 +03:00
pdb_set_logoff_time ( sampass , logoff_time , PDB_SET ) ;
2002-03-02 13:16:28 +03:00
}
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
if ( ! get_single_attribute ( ldap_state - > ldap_struct , entry , " kickoffTime " , temp ) ) {
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
2002-03-02 13:16:28 +03:00
kickoff_time = ( time_t ) atol ( temp ) ;
2002-11-02 06:47:48 +03:00
pdb_set_kickoff_time ( sampass , kickoff_time , PDB_SET ) ;
2002-03-02 13:16:28 +03:00
}
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
if ( ! get_single_attribute ( ldap_state - > ldap_struct , entry , " pwdCanChange " , temp ) ) {
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
2002-03-02 13:16:28 +03:00
pass_can_change_time = ( time_t ) atol ( temp ) ;
2002-11-02 06:47:48 +03:00
pdb_set_pass_can_change_time ( sampass , pass_can_change_time , PDB_SET ) ;
2002-03-02 13:16:28 +03:00
}
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
if ( ! get_single_attribute ( ldap_state - > ldap_struct , entry , " pwdMustChange " , temp ) ) {
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
2002-03-02 13:16:28 +03:00
pass_must_change_time = ( time_t ) atol ( temp ) ;
2002-11-02 06:47:48 +03:00
pdb_set_pass_must_change_time ( sampass , pass_must_change_time , PDB_SET ) ;
2002-03-02 13:16:28 +03:00
}
2001-09-26 00:21:21 +04:00
/* recommend that 'gecos' and 'displayName' should refer to the same
2002-03-02 13:16:28 +03:00
* attribute OID . userFullName depreciated , only used by Samba
* primary rules of LDAP : don ' t make a new attribute when one is already defined
2001-12-31 03:06:51 +03:00
* that fits your needs ; using cn then displayName rather than ' userFullName '
2001-09-26 00:21:21 +04:00
*/
2002-11-02 06:47:48 +03:00
if ( ! get_single_attribute ( ldap_state - > ldap_struct , entry , " cn " , fullname ) ) {
if ( ! get_single_attribute ( ldap_state - > ldap_struct , entry , " displayName " , fullname ) ) {
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
2002-11-02 06:47:48 +03:00
pdb_set_fullname ( sampass , fullname , PDB_SET ) ;
2002-04-08 05:52:44 +04:00
}
} else {
2002-11-02 06:47:48 +03:00
pdb_set_fullname ( sampass , fullname , PDB_SET ) ;
2001-09-26 00:21:21 +04:00
}
2002-11-02 06:47:48 +03:00
if ( ! get_single_attribute ( ldap_state - > ldap_struct , entry , " homeDrive " , dir_drive ) ) {
2002-07-15 14:35:28 +04:00
pdb_set_dir_drive ( sampass , talloc_sub_specified ( sampass - > mem_ctx ,
lp_logon_drive ( ) ,
username , domain ,
uid , gid ) ,
2002-11-02 06:47:48 +03:00
PDB_DEFAULT ) ;
2002-04-08 05:52:44 +04:00
} else {
2002-11-02 06:47:48 +03:00
pdb_set_dir_drive ( sampass , dir_drive , PDB_SET ) ;
2002-04-08 05:52:44 +04:00
}
2001-10-10 21:04:23 +04:00
2002-11-02 06:47:48 +03:00
if ( ! get_single_attribute ( ldap_state - > ldap_struct , entry , " smbHome " , homedir ) ) {
2002-07-15 14:35:28 +04:00
pdb_set_homedir ( sampass , talloc_sub_specified ( sampass - > mem_ctx ,
lp_logon_home ( ) ,
username , domain ,
uid , gid ) ,
2002-11-02 06:47:48 +03:00
PDB_DEFAULT ) ;
2002-04-08 05:52:44 +04:00
} else {
2002-11-02 06:47:48 +03:00
pdb_set_homedir ( sampass , homedir , PDB_SET ) ;
2002-04-08 05:52:44 +04:00
}
2001-10-10 21:04:23 +04:00
2002-11-02 06:47:48 +03:00
if ( ! get_single_attribute ( ldap_state - > ldap_struct , entry , " scriptPath " , logon_script ) ) {
2002-07-15 14:35:28 +04:00
pdb_set_logon_script ( sampass , talloc_sub_specified ( sampass - > mem_ctx ,
lp_logon_script ( ) ,
username , domain ,
uid , gid ) ,
2002-11-02 06:47:48 +03:00
PDB_DEFAULT ) ;
2002-04-08 05:52:44 +04:00
} else {
2002-11-02 06:47:48 +03:00
pdb_set_logon_script ( sampass , logon_script , PDB_SET ) ;
2002-04-08 05:52:44 +04:00
}
2001-10-10 21:04:23 +04:00
2002-11-02 06:47:48 +03:00
if ( ! get_single_attribute ( ldap_state - > ldap_struct , entry , " profilePath " , profile_path ) ) {
2002-07-15 14:35:28 +04:00
pdb_set_profile_path ( sampass , talloc_sub_specified ( sampass - > mem_ctx ,
lp_logon_path ( ) ,
username , domain ,
uid , gid ) ,
2002-11-02 06:47:48 +03:00
PDB_DEFAULT ) ;
2002-04-08 05:52:44 +04:00
} else {
2002-11-02 06:47:48 +03:00
pdb_set_profile_path ( sampass , profile_path , PDB_SET ) ;
2002-04-08 05:52:44 +04:00
}
2002-11-02 06:47:48 +03:00
if ( ! get_single_attribute ( ldap_state - > ldap_struct , entry , " description " , acct_desc ) ) {
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
2002-11-02 06:47:48 +03:00
pdb_set_acct_desc ( sampass , acct_desc , PDB_SET ) ;
2002-04-08 05:52:44 +04:00
}
2002-11-02 06:47:48 +03:00
if ( ! get_single_attribute ( ldap_state - > ldap_struct , entry , " userWorkstations " , workstations ) ) {
2002-04-08 05:52:44 +04:00
/* leave as default */ ;
} else {
2002-11-02 06:47:48 +03:00
pdb_set_workstations ( sampass , workstations , PDB_SET ) ;
2002-04-08 05:52:44 +04:00
}
2001-09-26 00:21:21 +04:00
/* FIXME: hours stuff should be cleaner */
2001-12-31 03:06:51 +03:00
2001-09-26 00:21:21 +04:00
logon_divs = 168 ;
hours_len = 21 ;
memset ( hours , 0xff , hours_len ) ;
2002-11-02 06:47:48 +03:00
if ( ! get_single_attribute ( ldap_state - > ldap_struct , entry , " lmPassword " , temp ) ) {
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
pdb_gethexpwd ( temp , smblmpwd ) ;
2002-08-17 21:00:51 +04:00
memset ( ( char * ) temp , ' \0 ' , strlen ( temp ) + 1 ) ;
2002-11-02 06:47:48 +03:00
if ( ! pdb_set_lanman_passwd ( sampass , smblmpwd , PDB_SET ) )
2002-04-08 05:52:44 +04:00
return False ;
2002-08-17 21:00:51 +04:00
ZERO_STRUCT ( smblmpwd ) ;
2002-04-08 05:52:44 +04:00
}
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
if ( ! get_single_attribute ( ldap_state - > ldap_struct , entry , " ntPassword " , temp ) ) {
2002-04-08 05:52:44 +04:00
/* leave as default */
} else {
pdb_gethexpwd ( temp , smbntpwd ) ;
2002-08-17 21:00:51 +04:00
memset ( ( char * ) temp , ' \0 ' , strlen ( temp ) + 1 ) ;
2002-11-02 06:47:48 +03:00
if ( ! pdb_set_nt_passwd ( sampass , smbntpwd , PDB_SET ) )
2002-04-08 05:52:44 +04:00
return False ;
2002-08-17 21:00:51 +04:00
ZERO_STRUCT ( smbntpwd ) ;
2002-04-08 05:52:44 +04:00
}
2002-11-02 06:47:48 +03:00
if ( ! get_single_attribute ( ldap_state - > ldap_struct , entry , " acctFlags " , temp ) ) {
2001-09-26 00:21:21 +04:00
acct_ctrl | = ACB_NORMAL ;
2002-04-08 05:52:44 +04:00
} else {
acct_ctrl = pdb_decode_acct_ctrl ( temp ) ;
if ( acct_ctrl = = 0 )
acct_ctrl | = ACB_NORMAL ;
2002-11-02 06:47:48 +03:00
pdb_set_acct_ctrl ( sampass , acct_ctrl , PDB_SET ) ;
2002-04-08 05:52:44 +04:00
}
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
pdb_set_hours_len ( sampass , hours_len , PDB_SET ) ;
pdb_set_logon_divs ( sampass , logon_divs , PDB_SET ) ;
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
pdb_set_munged_dial ( sampass , munged_dial , PDB_SET ) ;
2001-12-31 03:06:51 +03:00
2002-11-02 06:47:48 +03:00
/* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */
/* pdb_set_unknown_5(sampass, unknown5, PDB_SET); */
/* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
pdb_set_hours ( sampass , hours , PDB_SET ) ;
2001-09-26 00:21:21 +04:00
return True ;
}
2002-11-02 06:47:48 +03:00
static BOOL need_ldap_mod ( BOOL pdb_add , const SAM_ACCOUNT * sampass , enum pdb_elements element ) {
if ( pdb_add ) {
return ( ! IS_SAM_DEFAULT ( sampass , element ) ) ;
} else {
return IS_SAM_CHANGED ( sampass , element ) ;
}
}
2001-09-26 00:21:21 +04:00
/**********************************************************************
Initialize SAM_ACCOUNT from an LDAP query
( Based on init_buffer_from_sam in pdb_tdb . c )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-02 13:16:28 +03:00
static BOOL init_ldap_from_sam ( struct ldapsam_privates * ldap_state ,
LDAPMod * * * mods , int ldap_op ,
2002-11-02 06:47:48 +03:00
BOOL pdb_add ,
2002-03-02 13:16:28 +03:00
const SAM_ACCOUNT * sampass )
2001-09-26 00:21:21 +04:00
{
pstring temp ;
2002-03-02 13:16:28 +03:00
uint32 rid ;
2001-09-26 00:21:21 +04:00
2001-12-30 22:21:25 +03:00
if ( mods = = NULL | | sampass = = NULL ) {
DEBUG ( 0 , ( " init_ldap_from_sam: NULL parameters found! \n " ) ) ;
return False ;
}
2001-09-26 00:21:21 +04:00
* mods = NULL ;
/*
* took out adding " objectclass: sambaAccount "
* do this on a per - mod basis
*/
2002-11-02 06:47:48 +03:00
if ( need_ldap_mod ( pdb_add , sampass , PDB_USERNAME ) ) {
make_a_mod ( mods , ldap_op , " uid " , pdb_get_username ( sampass ) ) ;
DEBUG ( 2 , ( " Setting entry for user: %s \n " , pdb_get_username ( sampass ) ) ) ;
}
if ( ( rid = pdb_get_user_rid ( sampass ) ) ! = 0 ) {
if ( need_ldap_mod ( pdb_add , sampass , PDB_USERSID ) ) {
slprintf ( temp , sizeof ( temp ) - 1 , " %i " , rid ) ;
make_a_mod ( mods , ldap_op , " rid " , temp ) ;
}
} else if ( ! IS_SAM_DEFAULT ( sampass , PDB_UID ) ) {
2002-07-15 14:35:28 +04:00
rid = fallback_pdb_uid_to_user_rid ( pdb_get_uid ( sampass ) ) ;
2002-11-02 06:47:48 +03:00
slprintf ( temp , sizeof ( temp ) - 1 , " %i " , rid ) ;
make_a_mod ( mods , ldap_op , " rid " , temp ) ;
2002-03-02 13:16:28 +03:00
} else if ( ldap_state - > permit_non_unix_accounts ) {
rid = ldapsam_get_next_available_nua_rid ( ldap_state ) ;
if ( rid = = 0 ) {
DEBUG ( 0 , ( " NO user RID specified on account %s, and findining next available NUA RID failed, cannot store! \n " , pdb_get_username ( sampass ) ) ) ;
return False ;
}
2002-11-02 06:47:48 +03:00
slprintf ( temp , sizeof ( temp ) - 1 , " %i " , rid ) ;
make_a_mod ( mods , ldap_op , " rid " , temp ) ;
2002-03-02 13:16:28 +03:00
} else {
DEBUG ( 0 , ( " NO user RID specified on account %s, cannot store! \n " , pdb_get_username ( sampass ) ) ) ;
return False ;
}
2001-09-26 00:21:21 +04:00
2002-03-02 13:16:28 +03:00
2002-11-02 06:47:48 +03:00
if ( ( rid = pdb_get_group_rid ( sampass ) ) ! = 0 ) {
if ( need_ldap_mod ( pdb_add , sampass , PDB_GROUPSID ) ) {
slprintf ( temp , sizeof ( temp ) - 1 , " %i " , rid ) ;
make_a_mod ( mods , ldap_op , " primaryGroupID " , temp ) ;
}
} else if ( ! IS_SAM_DEFAULT ( sampass , PDB_GID ) ) {
2002-03-02 13:16:28 +03:00
rid = pdb_gid_to_group_rid ( pdb_get_gid ( sampass ) ) ;
2002-11-02 06:47:48 +03:00
slprintf ( temp , sizeof ( temp ) - 1 , " %i " , rid ) ;
make_a_mod ( mods , ldap_op , " primaryGroupID " , temp ) ;
2002-03-02 13:16:28 +03:00
} else if ( ldap_state - > permit_non_unix_accounts ) {
rid = DOMAIN_GROUP_RID_USERS ;
2002-11-02 06:47:48 +03:00
slprintf ( temp , sizeof ( temp ) - 1 , " %i " , rid ) ;
make_a_mod ( mods , ldap_op , " primaryGroupID " , temp ) ;
2002-03-02 13:16:28 +03:00
} else {
DEBUG ( 0 , ( " NO group RID specified on account %s, cannot store! \n " , pdb_get_username ( sampass ) ) ) ;
return False ;
}
2001-09-26 00:21:21 +04:00
/* displayName, cn, and gecos should all be the same
2002-10-01 17:10:57 +04:00
* most easily accomplished by giving them the same OID
* gecos isn ' t set here b / c it should be handled by the
* add - user script
2001-09-26 00:21:21 +04:00
*/
2002-11-02 06:47:48 +03:00
if ( need_ldap_mod ( pdb_add , sampass , PDB_FULLNAME ) ) {
make_a_mod ( mods , ldap_op , " displayName " , pdb_get_fullname ( sampass ) ) ;
make_a_mod ( mods , ldap_op , " cn " , pdb_get_fullname ( sampass ) ) ;
}
if ( need_ldap_mod ( pdb_add , sampass , PDB_ACCTDESC ) ) {
make_a_mod ( mods , ldap_op , " description " , pdb_get_acct_desc ( sampass ) ) ;
}
if ( need_ldap_mod ( pdb_add , sampass , PDB_WORKSTATIONS ) ) {
make_a_mod ( mods , ldap_op , " userWorkstations " , pdb_get_workstations ( sampass ) ) ;
}
2001-12-31 03:06:51 +03:00
/*
* Only updates fields which have been set ( not defaults from smb . conf )
*/
2002-11-02 06:47:48 +03:00
if ( need_ldap_mod ( pdb_add , sampass , PDB_SMBHOME ) ) {
2002-03-02 13:16:28 +03:00
make_a_mod ( mods , ldap_op , " smbHome " , pdb_get_homedir ( sampass ) ) ;
2002-11-02 06:47:48 +03:00
}
if ( need_ldap_mod ( pdb_add , sampass , PDB_DRIVE ) ) {
2002-08-17 21:00:51 +04:00
make_a_mod ( mods , ldap_op , " homeDrive " , pdb_get_dir_drive ( sampass ) ) ;
2002-11-02 06:47:48 +03:00
}
2002-03-02 13:16:28 +03:00
2002-11-02 06:47:48 +03:00
if ( need_ldap_mod ( pdb_add , sampass , PDB_LOGONSCRIPT ) ) {
2002-03-02 13:16:28 +03:00
make_a_mod ( mods , ldap_op , " scriptPath " , pdb_get_logon_script ( sampass ) ) ;
2002-11-02 06:47:48 +03:00
}
if ( need_ldap_mod ( pdb_add , sampass , PDB_PROFILE ) )
2002-03-02 13:16:28 +03:00
make_a_mod ( mods , ldap_op , " profilePath " , pdb_get_profile_path ( sampass ) ) ;
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
if ( need_ldap_mod ( pdb_add , sampass , PDB_LOGONTIME ) ) {
2002-03-02 13:16:28 +03:00
slprintf ( temp , sizeof ( temp ) - 1 , " %li " , pdb_get_logon_time ( sampass ) ) ;
make_a_mod ( mods , ldap_op , " logonTime " , temp ) ;
}
2001-12-31 03:06:51 +03:00
2002-11-02 06:47:48 +03:00
if ( need_ldap_mod ( pdb_add , sampass , PDB_LOGOFFTIME ) ) {
2002-03-02 13:16:28 +03:00
slprintf ( temp , sizeof ( temp ) - 1 , " %li " , pdb_get_logoff_time ( sampass ) ) ;
make_a_mod ( mods , ldap_op , " logoffTime " , temp ) ;
}
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
if ( need_ldap_mod ( pdb_add , sampass , PDB_KICKOFFTIME ) ) {
2002-03-02 13:16:28 +03:00
slprintf ( temp , sizeof ( temp ) - 1 , " %li " , pdb_get_kickoff_time ( sampass ) ) ;
make_a_mod ( mods , ldap_op , " kickoffTime " , temp ) ;
}
2002-09-25 19:19:00 +04:00
2002-11-02 06:47:48 +03:00
if ( need_ldap_mod ( pdb_add , sampass , PDB_CANCHANGETIME ) ) {
2002-03-02 13:16:28 +03:00
slprintf ( temp , sizeof ( temp ) - 1 , " %li " , pdb_get_pass_can_change_time ( sampass ) ) ;
make_a_mod ( mods , ldap_op , " pwdCanChange " , temp ) ;
}
2002-11-02 06:47:48 +03:00
if ( need_ldap_mod ( pdb_add , sampass , PDB_MUSTCHANGETIME ) ) {
2002-03-02 13:16:28 +03:00
slprintf ( temp , sizeof ( temp ) - 1 , " %li " , pdb_get_pass_must_change_time ( sampass ) ) ;
make_a_mod ( mods , ldap_op , " pwdMustChange " , temp ) ;
}
2001-09-26 00:21:21 +04:00
2002-09-25 19:19:00 +04:00
if ( ( pdb_get_acct_ctrl ( sampass ) & ( ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST ) ) | |
( lp_ldap_passwd_sync ( ) ! = LDAP_PASSWD_SYNC_ONLY ) ) {
2002-11-02 06:47:48 +03:00
if ( need_ldap_mod ( pdb_add , sampass , PDB_LMPASSWD ) ) {
pdb_sethexpwd ( temp , pdb_get_lanman_passwd ( sampass ) , pdb_get_acct_ctrl ( sampass ) ) ;
make_a_mod ( mods , ldap_op , " lmPassword " , temp ) ;
}
if ( need_ldap_mod ( pdb_add , sampass , PDB_NTPASSWD ) ) {
pdb_sethexpwd ( temp , pdb_get_nt_passwd ( sampass ) , pdb_get_acct_ctrl ( sampass ) ) ;
make_a_mod ( mods , ldap_op , " ntPassword " , temp ) ;
}
if ( need_ldap_mod ( pdb_add , sampass , PDB_PASSLASTSET ) ) {
slprintf ( temp , sizeof ( temp ) - 1 , " %li " , pdb_get_pass_last_set_time ( sampass ) ) ;
make_a_mod ( mods , ldap_op , " pwdLastSet " , temp ) ;
}
2002-09-25 19:19:00 +04:00
}
/* FIXME: Hours stuff goes in LDAP */
2002-11-02 06:47:48 +03:00
if ( need_ldap_mod ( pdb_add , sampass , PDB_ACCTCTRL ) ) {
make_a_mod ( mods , ldap_op , " acctFlags " , pdb_encode_acct_ctrl ( pdb_get_acct_ctrl ( sampass ) ,
NEW_PW_FORMAT_SPACE_PADDED_LEN ) ) ;
}
2001-09-26 00:21:21 +04:00
return True ;
}
2002-03-02 13:16:28 +03:00
/**********************************************************************
Connect to LDAP server and find the next available RID .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-02 06:47:48 +03:00
static uint32 check_nua_rid_is_avail ( struct ldapsam_privates * ldap_state , uint32 top_rid )
2002-03-02 13:16:28 +03:00
{
LDAPMessage * result ;
uint32 final_rid = ( top_rid & ( ~ USER_RID_TYPE ) ) + RID_MULTIPLIER ;
if ( top_rid = = 0 ) {
return 0 ;
}
if ( final_rid < ldap_state - > low_nua_rid | | final_rid > ldap_state - > high_nua_rid ) {
return 0 ;
}
2002-11-02 06:47:48 +03:00
if ( ldapsam_search_one_user_by_rid ( ldap_state , final_rid , & result ) ! = LDAP_SUCCESS ) {
2002-03-02 13:16:28 +03:00
DEBUG ( 0 , ( " Cannot allocate NUA RID %d (0x%x), as the confirmation search failed! \n " , final_rid , final_rid ) ) ;
ldap_msgfree ( result ) ;
2002-09-25 19:19:00 +04:00
return 0 ;
2002-03-02 13:16:28 +03:00
}
2002-11-02 06:47:48 +03:00
if ( ldap_count_entries ( ldap_state - > ldap_struct , result ) ! = 0 ) {
2002-03-02 13:16:28 +03:00
DEBUG ( 0 , ( " Cannot allocate NUA RID %d (0x%x), as the RID is already in use!! \n " , final_rid , final_rid ) ) ;
ldap_msgfree ( result ) ;
2002-09-25 19:19:00 +04:00
return 0 ;
2002-03-02 13:16:28 +03:00
}
DEBUG ( 5 , ( " NUA RID %d (0x%x), declared valid \n " , final_rid , final_rid ) ) ;
2002-09-25 19:19:00 +04:00
ldap_msgfree ( result ) ;
2002-03-02 13:16:28 +03:00
return final_rid ;
}
/**********************************************************************
Extract the RID from an LDAP entry
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-02 06:47:48 +03:00
static uint32 entry_to_user_rid ( struct ldapsam_privates * ldap_state , LDAPMessage * entry ) {
2002-03-02 13:16:28 +03:00
uint32 rid ;
SAM_ACCOUNT * user = NULL ;
if ( ! NT_STATUS_IS_OK ( pdb_init_sam ( & user ) ) ) {
return 0 ;
}
2002-11-02 06:47:48 +03:00
if ( init_sam_from_ldap ( ldap_state , user , entry ) ) {
2002-03-02 13:16:28 +03:00
rid = pdb_get_user_rid ( user ) ;
} else {
rid = 0 ;
}
pdb_free_sam ( & user ) ;
if ( rid > = ldap_state - > low_nua_rid & & rid < = ldap_state - > high_nua_rid ) {
return rid ;
}
return 0 ;
}
/**********************************************************************
Connect to LDAP server and find the next available RID .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-02 06:47:48 +03:00
static uint32 search_top_nua_rid ( struct ldapsam_privates * ldap_state )
2002-03-02 13:16:28 +03:00
{
int rc ;
pstring filter ;
LDAPMessage * result ;
LDAPMessage * entry ;
char * final_filter = NULL ;
uint32 top_rid = 0 ;
uint32 count ;
uint32 rid ;
pstrcpy ( filter , lp_ldap_filter ( ) ) ;
all_string_sub ( filter , " %u " , " * " , sizeof ( pstring ) ) ;
#if 0
asprintf ( & final_filter , " (&(%s)(&(rid>=%d)(rid<=%d))) " , filter , ldap_state - > low_nua_rid , ldap_state - > high_nua_rid ) ;
# else
final_filter = strdup ( filter ) ;
# endif
DEBUG ( 2 , ( " ldapsam_get_next_available_nua_rid: searching for:[%s] \n " , final_filter ) ) ;
2002-11-02 06:47:48 +03:00
rc = ldapsam_search ( ldap_state , lp_ldap_suffix ( ) ,
2002-09-25 19:19:00 +04:00
LDAP_SCOPE_SUBTREE , final_filter , ( char * * ) attr , 0 ,
2002-03-02 13:16:28 +03:00
& result ) ;
2002-09-25 19:19:00 +04:00
if ( rc ! = LDAP_SUCCESS ) {
2002-03-02 13:16:28 +03:00
DEBUG ( 3 , ( " LDAP search failed! cannot find base for NUA RIDs: %s \n " , ldap_err2string ( rc ) ) ) ;
DEBUGADD ( 3 , ( " Query was: %s, %s \n " , lp_ldap_suffix ( ) , final_filter ) ) ;
free ( final_filter ) ;
ldap_msgfree ( result ) ;
result = NULL ;
return 0 ;
}
2002-11-02 06:47:48 +03:00
count = ldap_count_entries ( ldap_state - > ldap_struct , result ) ;
2002-03-02 13:16:28 +03:00
DEBUG ( 2 , ( " search_top_nua_rid: %d entries in the base! \n " , count ) ) ;
if ( count = = 0 ) {
DEBUG ( 3 , ( " LDAP search returned no records, assuming no non-unix-accounts present!: %s \n " , ldap_err2string ( rc ) ) ) ;
DEBUGADD ( 3 , ( " Query was: %s, %s \n " , lp_ldap_suffix ( ) , final_filter ) ) ;
free ( final_filter ) ;
ldap_msgfree ( result ) ;
result = NULL ;
return ldap_state - > low_nua_rid ;
}
free ( final_filter ) ;
2002-11-02 06:47:48 +03:00
entry = ldap_first_entry ( ldap_state - > ldap_struct , result ) ;
2002-03-02 13:16:28 +03:00
2002-11-02 06:47:48 +03:00
top_rid = entry_to_user_rid ( ldap_state , entry ) ;
2002-03-02 13:16:28 +03:00
2002-11-02 06:47:48 +03:00
while ( ( entry = ldap_next_entry ( ldap_state - > ldap_struct , entry ) ) ) {
2002-03-02 13:16:28 +03:00
2002-11-02 06:47:48 +03:00
rid = entry_to_user_rid ( ldap_state , entry ) ;
2002-03-02 13:16:28 +03:00
if ( rid > top_rid ) {
top_rid = rid ;
}
}
ldap_msgfree ( result ) ;
2002-07-15 14:35:28 +04:00
if ( top_rid < ldap_state - > low_nua_rid )
top_rid = ldap_state - > low_nua_rid ;
2002-03-02 13:16:28 +03:00
return top_rid ;
}
/**********************************************************************
Connect to LDAP server and find the next available RID .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static uint32 ldapsam_get_next_available_nua_rid ( struct ldapsam_privates * ldap_state ) {
uint32 next_nua_rid ;
uint32 top_nua_rid ;
2002-11-02 06:47:48 +03:00
top_nua_rid = search_top_nua_rid ( ldap_state ) ;
2002-03-02 13:16:28 +03:00
next_nua_rid = check_nua_rid_is_avail ( ldap_state ,
2002-11-02 06:47:48 +03:00
top_nua_rid ) ;
2002-03-02 13:16:28 +03:00
return next_nua_rid ;
}
2001-09-26 00:21:21 +04:00
/**********************************************************************
Connect to LDAP server for password enumeration
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-26 22:58:34 +04:00
static NTSTATUS ldapsam_setsampwent ( struct pdb_methods * my_methods , BOOL update )
2001-09-26 00:21:21 +04:00
{
2002-07-15 14:35:28 +04:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
2001-09-26 00:21:21 +04:00
int rc ;
pstring filter ;
pstrcpy ( filter , lp_ldap_filter ( ) ) ;
all_string_sub ( filter , " %u " , " * " , sizeof ( pstring ) ) ;
2002-11-02 06:47:48 +03:00
rc = ldapsam_search ( ldap_state , lp_ldap_suffix ( ) ,
2002-09-25 19:19:00 +04:00
LDAP_SCOPE_SUBTREE , filter , ( char * * ) attr , 0 ,
2002-03-02 13:16:28 +03:00
& ldap_state - > result ) ;
2001-09-26 00:21:21 +04:00
2002-09-25 19:19:00 +04:00
if ( rc ! = LDAP_SUCCESS ) {
2001-09-26 00:21:21 +04:00
DEBUG ( 0 , ( " LDAP search failed: %s \n " , ldap_err2string ( rc ) ) ) ;
DEBUG ( 3 , ( " Query was: %s, %s \n " , lp_ldap_suffix ( ) , filter ) ) ;
2002-03-02 13:16:28 +03:00
ldap_msgfree ( ldap_state - > result ) ;
ldap_state - > result = NULL ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2001-09-26 00:21:21 +04:00
}
2002-03-02 13:16:28 +03:00
DEBUG ( 2 , ( " ldapsam_setsampwent: %d entries in the base! \n " ,
ldap_count_entries ( ldap_state - > ldap_struct ,
ldap_state - > result ) ) ) ;
2001-09-26 00:21:21 +04:00
2002-03-02 13:16:28 +03:00
ldap_state - > entry = ldap_first_entry ( ldap_state - > ldap_struct ,
ldap_state - > result ) ;
ldap_state - > index = 0 ;
2001-09-26 00:21:21 +04:00
2002-09-26 22:58:34 +04:00
return NT_STATUS_OK ;
2001-09-26 00:21:21 +04:00
}
/**********************************************************************
End enumeration of the LDAP password list
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-15 14:35:28 +04:00
static void ldapsam_endsampwent ( struct pdb_methods * my_methods )
2001-09-26 00:21:21 +04:00
{
2002-07-15 14:35:28 +04:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
2002-11-02 06:47:48 +03:00
if ( ldap_state - > result ) {
2002-03-02 13:16:28 +03:00
ldap_msgfree ( ldap_state - > result ) ;
ldap_state - > result = NULL ;
2001-09-26 00:21:21 +04:00
}
}
/**********************************************************************
Get the next entry in the LDAP password database
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-26 22:58:34 +04:00
static NTSTATUS ldapsam_getsampwent ( struct pdb_methods * my_methods , SAM_ACCOUNT * user )
2001-09-26 00:21:21 +04:00
{
2002-09-26 22:58:34 +04:00
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL ;
2002-07-15 14:35:28 +04:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
2002-09-26 22:58:34 +04:00
BOOL bret = False ;
2001-09-26 00:21:21 +04:00
2002-08-17 21:00:51 +04:00
/* The rebind proc needs this *HACK*. We are not multithreaded, so
this will work , but it ' s not nice . */
static_ldap_state = ldap_state ;
2002-09-26 22:58:34 +04:00
while ( ! bret ) {
2002-03-02 13:16:28 +03:00
if ( ! ldap_state - > entry )
2002-09-26 22:58:34 +04:00
return ret ;
2002-03-02 13:16:28 +03:00
ldap_state - > index + + ;
2002-11-02 06:47:48 +03:00
bret = init_sam_from_ldap ( ldap_state , user , ldap_state - > entry ) ;
2002-03-02 13:16:28 +03:00
ldap_state - > entry = ldap_next_entry ( ldap_state - > ldap_struct ,
2002-09-25 19:19:00 +04:00
ldap_state - > entry ) ;
2002-03-01 18:17:10 +03:00
}
2001-09-26 00:21:21 +04:00
2002-09-26 22:58:34 +04:00
return NT_STATUS_OK ;
2001-09-26 00:21:21 +04:00
}
/**********************************************************************
Get SAM_ACCOUNT entry from LDAP by username
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-26 22:58:34 +04:00
static NTSTATUS ldapsam_getsampwnam ( struct pdb_methods * my_methods , SAM_ACCOUNT * user , const char * sname )
2001-09-26 00:21:21 +04:00
{
2002-09-26 22:58:34 +04:00
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL ;
2002-07-15 14:35:28 +04:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
2001-09-26 00:21:21 +04:00
LDAPMessage * result ;
LDAPMessage * entry ;
2002-11-02 06:47:48 +03:00
if ( ldapsam_search_one_user_by_name ( ldap_state , sname , & result ) ! = LDAP_SUCCESS ) {
return NT_STATUS_UNSUCCESSFUL ;
2001-09-26 00:21:21 +04:00
}
2002-11-02 06:47:48 +03:00
if ( ldap_count_entries ( ldap_state - > ldap_struct , result ) < 1 ) {
2002-03-02 13:16:28 +03:00
DEBUG ( 4 ,
2001-09-26 00:21:21 +04:00
( " We don't find this user [%s] count=%d \n " , sname ,
2002-11-02 06:47:48 +03:00
ldap_count_entries ( ldap_state - > ldap_struct , result ) ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
2001-09-26 00:21:21 +04:00
}
2002-11-02 06:47:48 +03:00
entry = ldap_first_entry ( ldap_state - > ldap_struct , result ) ;
2002-09-25 19:19:00 +04:00
if ( entry ) {
2002-11-02 06:47:48 +03:00
if ( ! init_sam_from_ldap ( ldap_state , user , entry ) ) {
2002-08-17 21:00:51 +04:00
DEBUG ( 1 , ( " ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'! \n " , sname ) ) ;
2002-03-02 13:16:28 +03:00
ldap_msgfree ( result ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2002-03-02 13:16:28 +03:00
}
2001-09-26 00:21:21 +04:00
ldap_msgfree ( result ) ;
2002-09-26 22:58:34 +04:00
ret = NT_STATUS_OK ;
2002-09-25 19:19:00 +04:00
} else {
2001-09-26 00:21:21 +04:00
ldap_msgfree ( result ) ;
}
2002-09-26 22:58:34 +04:00
return ret ;
2001-09-26 00:21:21 +04:00
}
/**********************************************************************
Get SAM_ACCOUNT entry from LDAP by rid
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-26 22:58:34 +04:00
static NTSTATUS ldapsam_getsampwrid ( struct pdb_methods * my_methods , SAM_ACCOUNT * user , uint32 rid )
2001-09-26 00:21:21 +04:00
{
2002-09-26 22:58:34 +04:00
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL ;
2002-07-15 14:35:28 +04:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
2001-09-26 00:21:21 +04:00
LDAPMessage * result ;
LDAPMessage * entry ;
2002-11-02 06:47:48 +03:00
if ( ldapsam_search_one_user_by_rid ( ldap_state , rid , & result ) ! = LDAP_SUCCESS ) {
return NT_STATUS_UNSUCCESSFUL ;
2001-09-26 00:21:21 +04:00
}
2002-11-02 06:47:48 +03:00
if ( ldap_count_entries ( ldap_state - > ldap_struct , result ) < 1 ) {
2002-08-17 21:00:51 +04:00
DEBUG ( 4 ,
2001-09-26 00:21:21 +04:00
( " We don't find this rid [%i] count=%d \n " , rid ,
2002-11-02 06:47:48 +03:00
ldap_count_entries ( ldap_state - > ldap_struct , result ) ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
2001-09-26 00:21:21 +04:00
}
2002-11-02 06:47:48 +03:00
entry = ldap_first_entry ( ldap_state - > ldap_struct , result ) ;
2002-09-25 19:19:00 +04:00
if ( entry ) {
2002-11-02 06:47:48 +03:00
if ( ! init_sam_from_ldap ( ldap_state , user , entry ) ) {
2002-08-17 21:00:51 +04:00
DEBUG ( 1 , ( " ldapsam_getsampwrid: init_sam_from_ldap failed! \n " ) ) ;
2002-03-02 13:16:28 +03:00
ldap_msgfree ( result ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2002-03-02 13:16:28 +03:00
}
2001-09-26 00:21:21 +04:00
ldap_msgfree ( result ) ;
2002-09-26 22:58:34 +04:00
ret = NT_STATUS_OK ;
2002-09-25 19:19:00 +04:00
} else {
2001-09-26 00:21:21 +04:00
ldap_msgfree ( result ) ;
}
2002-09-26 22:58:34 +04:00
return ret ;
2001-09-26 00:21:21 +04:00
}
2002-09-26 22:58:34 +04:00
static NTSTATUS ldapsam_getsampwsid ( struct pdb_methods * my_methods , SAM_ACCOUNT * user , const DOM_SID * sid )
2002-07-15 14:35:28 +04:00
{
uint32 rid ;
if ( ! sid_peek_check_rid ( get_global_sam_sid ( ) , sid , & rid ) )
2002-09-26 22:58:34 +04:00
return NT_STATUS_UNSUCCESSFUL ;
2002-07-15 14:35:28 +04:00
return ldapsam_getsampwrid ( my_methods , user , rid ) ;
}
2002-11-02 06:47:48 +03:00
/********************************************************************
Do the actual modification - also change a plaittext passord if
it it set .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS ldapsam_modify_entry ( struct pdb_methods * my_methods ,
SAM_ACCOUNT * newpwd , char * dn ,
LDAPMod * * mods , int ldap_op , BOOL pdb_add )
2002-09-25 19:19:00 +04:00
{
2002-11-02 06:47:48 +03:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
2002-09-25 19:19:00 +04:00
int rc ;
2002-11-02 06:47:48 +03:00
if ( ! my_methods | | ! newpwd | | ! dn ) {
return NT_STATUS_INVALID_PARAMETER ;
}
if ( ! mods ) {
DEBUG ( 5 , ( " mods is empty: nothing to modify \n " ) ) ;
/* may be password change below however */
} else {
switch ( ldap_op )
{
case LDAP_MOD_ADD :
2002-09-25 19:19:00 +04:00
make_a_mod ( & mods , LDAP_MOD_ADD , " objectclass " , " account " ) ;
2002-11-02 06:47:48 +03:00
rc = ldapsam_add ( ldap_state , dn , mods ) ;
2002-09-25 19:19:00 +04:00
break ;
2002-11-02 06:47:48 +03:00
case LDAP_MOD_REPLACE :
rc = ldapsam_modify ( ldap_state , dn , mods ) ;
2002-09-25 19:19:00 +04:00
break ;
2002-11-02 06:47:48 +03:00
default :
DEBUG ( 0 , ( " Wrong LDAP operation type: %d! \n " , ldap_op ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
if ( rc ! = LDAP_SUCCESS ) {
char * ld_error ;
ldap_get_option ( ldap_state - > ldap_struct , LDAP_OPT_ERROR_STRING ,
& ld_error ) ;
DEBUG ( 1 ,
( " failed to %s user dn= %s with: %s \n \t %s \n " ,
ldap_op = = LDAP_MOD_ADD ? " add " : " modify " ,
dn , ldap_err2string ( rc ) ,
ld_error ) ) ;
free ( ld_error ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
2002-09-25 19:19:00 +04:00
}
# ifdef LDAP_EXOP_X_MODIFY_PASSWD
if ( ! ( pdb_get_acct_ctrl ( newpwd ) & ( ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST ) ) & &
( lp_ldap_passwd_sync ( ) ! = LDAP_PASSWD_SYNC_OFF ) & &
2002-11-02 06:47:48 +03:00
need_ldap_mod ( pdb_add , newpwd , PDB_PLAINTEXT_PW ) & &
2002-09-25 19:19:00 +04:00
( pdb_get_plaintext_passwd ( newpwd ) ! = NULL ) ) {
BerElement * ber ;
struct berval * bv ;
char * retoid ;
struct berval * retdata ;
if ( ( ber = ber_alloc_t ( LBER_USE_DER ) ) = = NULL ) {
DEBUG ( 0 , ( " ber_alloc_t returns NULL \n " ) ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2002-09-25 19:19:00 +04:00
}
ber_printf ( ber , " { " ) ;
ber_printf ( ber , " ts " , LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID , dn ) ;
ber_printf ( ber , " ts " , LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW , pdb_get_plaintext_passwd ( newpwd ) ) ;
ber_printf ( ber , " N} " ) ;
if ( ( rc = ber_flatten ( ber , & bv ) ) < 0 ) {
DEBUG ( 0 , ( " ber_flatten returns a value <0 \n " ) ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2002-09-25 19:19:00 +04:00
}
ber_free ( ber , 1 ) ;
2002-11-02 06:47:48 +03:00
if ( ( rc = ldapsam_extended_operation ( ldap_state , LDAP_EXOP_X_MODIFY_PASSWD ,
2002-09-25 19:19:00 +04:00
bv , NULL , NULL , & retoid , & retdata ) ) ! = LDAP_SUCCESS ) {
DEBUG ( 0 , ( " LDAP Password could not be changed for user %s: %s \n " ,
pdb_get_username ( newpwd ) , ldap_err2string ( rc ) ) ) ;
} else {
DEBUG ( 3 , ( " LDAP Password changed for user %s \n " , pdb_get_username ( newpwd ) ) ) ;
ber_bvfree ( retdata ) ;
ber_memfree ( retoid ) ;
}
ber_bvfree ( bv ) ;
}
# else
DEBUG ( 10 , ( " LDAP PASSWORD SYNC is not supported! \n " ) ) ;
# endif /* LDAP_EXOP_X_MODIFY_PASSWD */
2002-09-26 22:58:34 +04:00
return NT_STATUS_OK ;
2002-09-25 19:19:00 +04:00
}
2001-09-26 00:21:21 +04:00
/**********************************************************************
Delete entry from LDAP for username
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-26 22:58:34 +04:00
static NTSTATUS ldapsam_delete_sam_account ( struct pdb_methods * my_methods , SAM_ACCOUNT * sam_acct )
2001-09-26 00:21:21 +04:00
{
2002-07-15 14:35:28 +04:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
This is another *BIG* change...
Samba now features a pluggable passdb interface, along the same lines as the
one in use in the auth subsystem. In this case, only one backend may be active
at a time by the 'normal' interface, and only one backend per passdb_context is
permitted outside that.
This pluggable interface is designed to allow any number of passdb backends to
be compiled in, with the selection at runtime. The 'passdb backend' paramater
has been created (and documented!) to support this.
As such, configure has been modfied to allow (for example) --with-ldap and the
old smbpasswd to be selected at the same time.
This patch also introduces two new backends: smbpasswd_nua and tdbsam_nua.
These two backends accept 'non unix accounts', where the user does *not* exist
in /etc/passwd. These accounts' don't have UIDs in the unix sense, but to
avoid conflicts in the algroitmic mapping of RIDs, they use the values
specified in the 'non unix account range' paramter - in the same way as the
winbind ranges are specifed.
While I was at it, I cleaned up some of the code in pdb_tdb (code copied
directly from smbpasswd and not really considered properly). Most of this was
to do with % macro expansion on stored data. It isn't easy to get the macros
into the tdb, and the first password change will 'expand' them. tdbsam needs
to use a similar system to pdb_ldap in this regard.
This patch only makes minor adjustments to pdb_nisplus and pdb_ldap, becouse I
don't have the test facilities for these. I plan to incoroprate at least
pdb_ldap into this scheme after consultation with Jerry.
Each (converted) passdb module now no longer has any 'static' variables, and
only exports 1 init function outside its .c file.
The non-unix-account support in this patch has been proven! It is now possible
to join a win2k machine to a Samba PDC without an account in /etc/passwd!
Other changes:
Minor interface adjustments:
pdb_delete_sam_account() now takes a SAM_ACCOUNT, not a char*.
pdb_update_sam_account() no longer takes the 'override' argument that was being
ignored so often (every other passdb backend). Extra checks have been added in
some places.
Minor code changes:
smbpasswd no longer attempts to initialise the passdb at startup, this is
now done on first use.
pdbedit has lost some of its 'machine account' logic, as this behaviour is now
controlled by the passdb subsystem directly.
The samr subsystem no longer calls 'local password change', but does the pdb
interactions directly. This allow the ACB_ flags specifed to be transferred
direct to the backend, without interference.
Doco:
I've updated the doco to reflect some of the changes, and removed some paramters
no longer applicable to HEAD.
(This used to be commit ff354c99c585068af6dc1ff35a1f109a806b326b)
2002-01-20 17:30:58 +03:00
const char * sname ;
2001-09-26 00:21:21 +04:00
int rc ;
char * dn ;
LDAPMessage * entry ;
LDAPMessage * result ;
This is another *BIG* change...
Samba now features a pluggable passdb interface, along the same lines as the
one in use in the auth subsystem. In this case, only one backend may be active
at a time by the 'normal' interface, and only one backend per passdb_context is
permitted outside that.
This pluggable interface is designed to allow any number of passdb backends to
be compiled in, with the selection at runtime. The 'passdb backend' paramater
has been created (and documented!) to support this.
As such, configure has been modfied to allow (for example) --with-ldap and the
old smbpasswd to be selected at the same time.
This patch also introduces two new backends: smbpasswd_nua and tdbsam_nua.
These two backends accept 'non unix accounts', where the user does *not* exist
in /etc/passwd. These accounts' don't have UIDs in the unix sense, but to
avoid conflicts in the algroitmic mapping of RIDs, they use the values
specified in the 'non unix account range' paramter - in the same way as the
winbind ranges are specifed.
While I was at it, I cleaned up some of the code in pdb_tdb (code copied
directly from smbpasswd and not really considered properly). Most of this was
to do with % macro expansion on stored data. It isn't easy to get the macros
into the tdb, and the first password change will 'expand' them. tdbsam needs
to use a similar system to pdb_ldap in this regard.
This patch only makes minor adjustments to pdb_nisplus and pdb_ldap, becouse I
don't have the test facilities for these. I plan to incoroprate at least
pdb_ldap into this scheme after consultation with Jerry.
Each (converted) passdb module now no longer has any 'static' variables, and
only exports 1 init function outside its .c file.
The non-unix-account support in this patch has been proven! It is now possible
to join a win2k machine to a Samba PDC without an account in /etc/passwd!
Other changes:
Minor interface adjustments:
pdb_delete_sam_account() now takes a SAM_ACCOUNT, not a char*.
pdb_update_sam_account() no longer takes the 'override' argument that was being
ignored so often (every other passdb backend). Extra checks have been added in
some places.
Minor code changes:
smbpasswd no longer attempts to initialise the passdb at startup, this is
now done on first use.
pdbedit has lost some of its 'machine account' logic, as this behaviour is now
controlled by the passdb subsystem directly.
The samr subsystem no longer calls 'local password change', but does the pdb
interactions directly. This allow the ACB_ flags specifed to be transferred
direct to the backend, without interference.
Doco:
I've updated the doco to reflect some of the changes, and removed some paramters
no longer applicable to HEAD.
(This used to be commit ff354c99c585068af6dc1ff35a1f109a806b326b)
2002-01-20 17:30:58 +03:00
if ( ! sam_acct ) {
DEBUG ( 0 , ( " sam_acct was NULL! \n " ) ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
This is another *BIG* change...
Samba now features a pluggable passdb interface, along the same lines as the
one in use in the auth subsystem. In this case, only one backend may be active
at a time by the 'normal' interface, and only one backend per passdb_context is
permitted outside that.
This pluggable interface is designed to allow any number of passdb backends to
be compiled in, with the selection at runtime. The 'passdb backend' paramater
has been created (and documented!) to support this.
As such, configure has been modfied to allow (for example) --with-ldap and the
old smbpasswd to be selected at the same time.
This patch also introduces two new backends: smbpasswd_nua and tdbsam_nua.
These two backends accept 'non unix accounts', where the user does *not* exist
in /etc/passwd. These accounts' don't have UIDs in the unix sense, but to
avoid conflicts in the algroitmic mapping of RIDs, they use the values
specified in the 'non unix account range' paramter - in the same way as the
winbind ranges are specifed.
While I was at it, I cleaned up some of the code in pdb_tdb (code copied
directly from smbpasswd and not really considered properly). Most of this was
to do with % macro expansion on stored data. It isn't easy to get the macros
into the tdb, and the first password change will 'expand' them. tdbsam needs
to use a similar system to pdb_ldap in this regard.
This patch only makes minor adjustments to pdb_nisplus and pdb_ldap, becouse I
don't have the test facilities for these. I plan to incoroprate at least
pdb_ldap into this scheme after consultation with Jerry.
Each (converted) passdb module now no longer has any 'static' variables, and
only exports 1 init function outside its .c file.
The non-unix-account support in this patch has been proven! It is now possible
to join a win2k machine to a Samba PDC without an account in /etc/passwd!
Other changes:
Minor interface adjustments:
pdb_delete_sam_account() now takes a SAM_ACCOUNT, not a char*.
pdb_update_sam_account() no longer takes the 'override' argument that was being
ignored so often (every other passdb backend). Extra checks have been added in
some places.
Minor code changes:
smbpasswd no longer attempts to initialise the passdb at startup, this is
now done on first use.
pdbedit has lost some of its 'machine account' logic, as this behaviour is now
controlled by the passdb subsystem directly.
The samr subsystem no longer calls 'local password change', but does the pdb
interactions directly. This allow the ACB_ flags specifed to be transferred
direct to the backend, without interference.
Doco:
I've updated the doco to reflect some of the changes, and removed some paramters
no longer applicable to HEAD.
(This used to be commit ff354c99c585068af6dc1ff35a1f109a806b326b)
2002-01-20 17:30:58 +03:00
}
sname = pdb_get_username ( sam_acct ) ;
2001-09-26 00:21:21 +04:00
DEBUG ( 3 , ( " Deleting user %s from LDAP. \n " , sname ) ) ;
2002-11-02 06:47:48 +03:00
rc = ldapsam_search_one_user_by_name ( ldap_state , sname , & result ) ;
if ( ldap_count_entries ( ldap_state - > ldap_struct , result ) = = 0 ) {
2001-09-26 00:21:21 +04:00
DEBUG ( 0 , ( " User doesn't exit! \n " ) ) ;
ldap_msgfree ( result ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2001-09-26 00:21:21 +04:00
}
2002-11-02 06:47:48 +03:00
entry = ldap_first_entry ( ldap_state - > ldap_struct , result ) ;
dn = ldap_get_dn ( ldap_state - > ldap_struct , entry ) ;
2002-09-25 19:19:00 +04:00
ldap_msgfree ( result ) ;
2002-11-02 06:47:48 +03:00
rc = ldapsam_delete ( ldap_state , dn ) ;
2001-09-26 00:21:21 +04:00
ldap_memfree ( dn ) ;
if ( rc ! = LDAP_SUCCESS ) {
char * ld_error ;
2002-11-02 06:47:48 +03:00
ldap_get_option ( ldap_state - > ldap_struct , LDAP_OPT_ERROR_STRING , & ld_error ) ;
2001-09-26 00:21:21 +04:00
DEBUG ( 0 , ( " failed to delete user with uid = %s with: %s \n \t %s \n " ,
sname , ldap_err2string ( rc ) , ld_error ) ) ;
free ( ld_error ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2001-09-26 00:21:21 +04:00
}
DEBUG ( 2 , ( " successfully deleted uid = %s from the LDAP database \n " , sname ) ) ;
2002-09-26 22:58:34 +04:00
return NT_STATUS_OK ;
2001-09-26 00:21:21 +04:00
}
/**********************************************************************
Update SAM_ACCOUNT
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-26 22:58:34 +04:00
static NTSTATUS ldapsam_update_sam_account ( struct pdb_methods * my_methods , SAM_ACCOUNT * newpwd )
2001-09-26 00:21:21 +04:00
{
2002-09-26 22:58:34 +04:00
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL ;
2002-07-15 14:35:28 +04:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
2001-09-26 00:21:21 +04:00
int rc ;
char * dn ;
LDAPMessage * result ;
LDAPMessage * entry ;
LDAPMod * * mods ;
2002-11-02 06:47:48 +03:00
if ( ! init_ldap_from_sam ( ldap_state , & mods , LDAP_MOD_REPLACE , False , newpwd ) ) {
DEBUG ( 0 , ( " ldapsam_update_sam_account: init_ldap_from_sam failed! \n " ) ) ;
2001-09-26 00:21:21 +04:00
ldap_msgfree ( result ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2001-09-26 00:21:21 +04:00
}
2002-11-02 06:47:48 +03:00
if ( mods = = NULL ) {
DEBUG ( 4 , ( " mods is empty: nothing to update for user: %s \n " , pdb_get_username ( newpwd ) ) ) ;
return NT_STATUS_OK ;
}
rc = ldapsam_search_one_user_by_name ( ldap_state , pdb_get_username ( newpwd ) , & result ) ;
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
if ( ldap_count_entries ( ldap_state - > ldap_struct , result ) = = 0 ) {
DEBUG ( 0 , ( " No user to modify! \n " ) ) ;
2002-03-02 13:16:28 +03:00
ldap_msgfree ( result ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2002-03-02 13:16:28 +03:00
}
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
entry = ldap_first_entry ( ldap_state - > ldap_struct , result ) ;
dn = ldap_get_dn ( ldap_state - > ldap_struct , entry ) ;
2002-09-25 19:19:00 +04:00
ldap_msgfree ( result ) ;
2002-11-02 06:47:48 +03:00
ret = ldapsam_modify_entry ( my_methods , newpwd , dn , mods , LDAP_MOD_REPLACE , False ) ;
if ( NT_STATUS_IS_ERR ( ret ) ) {
2002-09-25 19:19:00 +04:00
DEBUG ( 0 , ( " failed to modify user with uid = %s \n " ,
pdb_get_username ( newpwd ) ) ) ;
ldap_mods_free ( mods , 1 ) ;
2002-09-26 22:58:34 +04:00
return ret ;
2001-09-26 00:21:21 +04:00
}
2002-09-25 19:19:00 +04:00
2001-09-26 00:21:21 +04:00
DEBUG ( 2 ,
( " successfully modified uid = %s in the LDAP database \n " ,
pdb_get_username ( newpwd ) ) ) ;
ldap_mods_free ( mods , 1 ) ;
2002-09-26 22:58:34 +04:00
return NT_STATUS_OK ;
2001-09-26 00:21:21 +04:00
}
/**********************************************************************
Add SAM_ACCOUNT to LDAP
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-26 22:58:34 +04:00
static NTSTATUS ldapsam_add_sam_account ( struct pdb_methods * my_methods , SAM_ACCOUNT * newpwd )
2001-09-26 00:21:21 +04:00
{
2002-09-26 22:58:34 +04:00
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL ;
2002-07-15 14:35:28 +04:00
struct ldapsam_privates * ldap_state = ( struct ldapsam_privates * ) my_methods - > private_data ;
2001-09-26 00:21:21 +04:00
int rc ;
pstring filter ;
2002-03-02 13:16:28 +03:00
LDAPMessage * result = NULL ;
2001-09-26 00:21:21 +04:00
pstring dn ;
2002-03-02 13:16:28 +03:00
LDAPMod * * mods = NULL ;
2001-12-31 03:06:51 +03:00
int ldap_op ;
uint32 num_result ;
2002-09-25 19:19:00 +04:00
2002-03-23 11:32:25 +03:00
const char * username = pdb_get_username ( newpwd ) ;
if ( ! username | | ! * username ) {
DEBUG ( 0 , ( " Cannot add user without a username! \n " ) ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2001-09-26 00:21:21 +04:00
}
2002-11-02 06:47:48 +03:00
rc = ldapsam_search_one_user_by_name ( ldap_state , username , & result ) ;
2001-09-26 00:21:21 +04:00
2002-11-02 06:47:48 +03:00
if ( ldap_count_entries ( ldap_state - > ldap_struct , result ) ! = 0 ) {
2001-09-26 00:21:21 +04:00
DEBUG ( 0 , ( " User already in the base, with samba properties \n " ) ) ;
ldap_msgfree ( result ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2001-09-26 00:21:21 +04:00
}
ldap_msgfree ( result ) ;
2002-03-23 11:32:25 +03:00
slprintf ( filter , sizeof ( filter ) - 1 , " uid=%s " , username ) ;
2002-11-02 06:47:48 +03:00
rc = ldapsam_search_one_user ( ldap_state , filter , & result ) ;
num_result = ldap_count_entries ( ldap_state - > ldap_struct , result ) ;
2001-12-31 03:06:51 +03:00
if ( num_result > 1 ) {
DEBUG ( 0 , ( " More than one user with that uid exists: bailing out! \n " ) ) ;
2002-03-23 11:32:25 +03:00
ldap_msgfree ( result ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2001-12-31 03:06:51 +03:00
}
/* Check if we need to update an existing entry */
if ( num_result = = 1 ) {
2001-09-26 00:21:21 +04:00
char * tmp ;
LDAPMessage * entry ;
2001-12-31 03:06:51 +03:00
2001-09-26 00:21:21 +04:00
DEBUG ( 3 , ( " User exists without samba properties: adding them \n " ) ) ;
ldap_op = LDAP_MOD_REPLACE ;
2002-11-02 06:47:48 +03:00
entry = ldap_first_entry ( ldap_state - > ldap_struct , result ) ;
tmp = ldap_get_dn ( ldap_state - > ldap_struct , entry ) ;
2001-09-26 00:21:21 +04:00
slprintf ( dn , sizeof ( dn ) - 1 , " %s " , tmp ) ;
ldap_memfree ( tmp ) ;
2002-09-25 19:19:00 +04:00
} else {
2001-12-31 03:06:51 +03:00
/* Check if we need to add an entry */
DEBUG ( 3 , ( " Adding new user \n " ) ) ;
ldap_op = LDAP_MOD_ADD ;
2002-03-23 11:32:25 +03:00
if ( username [ strlen ( username ) - 1 ] = = ' $ ' ) {
slprintf ( dn , sizeof ( dn ) - 1 , " uid=%s,%s " , username , lp_ldap_machine_suffix ( ) ) ;
} else {
slprintf ( dn , sizeof ( dn ) - 1 , " uid=%s,%s " , username , lp_ldap_user_suffix ( ) ) ;
2002-03-02 13:16:28 +03:00
}
2001-09-26 00:21:21 +04:00
}
ldap_msgfree ( result ) ;
2002-11-02 06:47:48 +03:00
if ( ! init_ldap_from_sam ( ldap_state , & mods , ldap_op , True , newpwd ) ) {
2002-03-02 13:16:28 +03:00
DEBUG ( 0 , ( " ldapsam_add_sam_account: init_ldap_from_sam failed! \n " ) ) ;
ldap_mods_free ( mods , 1 ) ;
2002-11-02 06:47:48 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2002-03-02 13:16:28 +03:00
}
2002-11-02 06:47:48 +03:00
if ( mods = = NULL ) {
DEBUG ( 0 , ( " mods is empty: nothing to add for user: %s \n " , pdb_get_username ( newpwd ) ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
2001-09-26 00:21:21 +04:00
make_a_mod ( & mods , LDAP_MOD_ADD , " objectclass " , " sambaAccount " ) ;
2002-11-02 06:47:48 +03:00
ret = ldapsam_modify_entry ( my_methods , newpwd , dn , mods , ldap_op , True ) ;
if ( NT_STATUS_IS_ERR ( ret ) ) {
2002-09-25 19:19:00 +04:00
DEBUG ( 0 , ( " failed to modify/add user with uid = %s (dn = %s) \n " ,
2002-11-02 06:47:48 +03:00
pdb_get_username ( newpwd ) , dn ) ) ;
2002-09-25 19:19:00 +04:00
ldap_mods_free ( mods , 1 ) ;
2002-09-26 22:58:34 +04:00
return ret ;
2001-09-26 00:21:21 +04:00
}
2002-09-25 19:19:00 +04:00
2001-09-26 00:21:21 +04:00
DEBUG ( 2 , ( " added: uid = %s in the LDAP database \n " , pdb_get_username ( newpwd ) ) ) ;
ldap_mods_free ( mods , 1 ) ;
2002-09-26 22:58:34 +04:00
return NT_STATUS_OK ;
2001-09-26 00:21:21 +04:00
}
2002-11-02 06:47:48 +03:00
static NTSTATUS lsapsam_getgrsid ( struct pdb_methods * methods , GROUP_MAP * map ,
DOM_SID sid , BOOL with_priv )
{
return get_group_map_from_sid ( sid , map , with_priv ) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
static NTSTATUS lsapsam_getgrgid ( struct pdb_methods * methods , GROUP_MAP * map ,
gid_t gid , BOOL with_priv )
{
return get_group_map_from_gid ( gid , map , with_priv ) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
static NTSTATUS lsapsam_getgrnam ( struct pdb_methods * methods , GROUP_MAP * map ,
char * name , BOOL with_priv )
{
return get_group_map_from_ntname ( name , map , with_priv ) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
static NTSTATUS lsapsam_add_group_mapping_entry ( struct pdb_methods * methods ,
GROUP_MAP * map )
{
return add_mapping_entry ( map , TDB_INSERT ) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
static NTSTATUS lsapsam_update_group_mapping_entry ( struct pdb_methods * methods ,
GROUP_MAP * map )
{
return add_mapping_entry ( map , TDB_REPLACE ) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
static NTSTATUS lsapsam_delete_group_mapping_entry ( struct pdb_methods * methods ,
DOM_SID sid )
{
return group_map_remove ( sid ) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
static NTSTATUS lsapsam_enum_group_mapping ( struct pdb_methods * methods ,
enum SID_NAME_USE sid_name_use ,
GROUP_MAP * * rmap , int * num_entries ,
BOOL unix_only , BOOL with_priv )
{
return enum_group_mapping ( sid_name_use , rmap , num_entries , unix_only ,
with_priv ) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
2002-03-02 13:16:28 +03:00
static void free_private_data ( void * * vp )
{
struct ldapsam_privates * * ldap_state = ( struct ldapsam_privates * * ) vp ;
2002-11-02 06:47:48 +03:00
ldapsam_close ( * ldap_state ) ;
2002-03-02 13:16:28 +03:00
2002-08-17 21:00:51 +04:00
if ( ( * ldap_state ) - > bind_secret ) {
memset ( ( * ldap_state ) - > bind_secret , ' \0 ' , strlen ( ( * ldap_state ) - > bind_secret ) ) ;
}
2002-11-02 06:47:48 +03:00
ldapsam_close ( * ldap_state ) ;
2002-08-17 21:00:51 +04:00
SAFE_FREE ( ( * ldap_state ) - > bind_dn ) ;
SAFE_FREE ( ( * ldap_state ) - > bind_secret ) ;
2002-03-02 13:16:28 +03:00
* ldap_state = NULL ;
/* No need to free any further, as it is talloc()ed */
}
NTSTATUS pdb_init_ldapsam ( PDB_CONTEXT * pdb_context , PDB_METHODS * * pdb_method , const char * location )
{
NTSTATUS nt_status ;
struct ldapsam_privates * ldap_state ;
if ( ! NT_STATUS_IS_OK ( nt_status = make_pdb_methods ( pdb_context - > mem_ctx , pdb_method ) ) ) {
return nt_status ;
}
( * pdb_method ) - > name = " ldapsam " ;
( * pdb_method ) - > setsampwent = ldapsam_setsampwent ;
( * pdb_method ) - > endsampwent = ldapsam_endsampwent ;
( * pdb_method ) - > getsampwent = ldapsam_getsampwent ;
( * pdb_method ) - > getsampwnam = ldapsam_getsampwnam ;
2002-07-15 14:35:28 +04:00
( * pdb_method ) - > getsampwsid = ldapsam_getsampwsid ;
2002-03-02 13:16:28 +03:00
( * pdb_method ) - > add_sam_account = ldapsam_add_sam_account ;
( * pdb_method ) - > update_sam_account = ldapsam_update_sam_account ;
( * pdb_method ) - > delete_sam_account = ldapsam_delete_sam_account ;
2002-11-02 06:47:48 +03:00
( * pdb_method ) - > getgrsid = lsapsam_getgrsid ;
( * pdb_method ) - > getgrgid = lsapsam_getgrgid ;
( * pdb_method ) - > getgrnam = lsapsam_getgrnam ;
( * pdb_method ) - > add_group_mapping_entry = lsapsam_add_group_mapping_entry ;
( * pdb_method ) - > update_group_mapping_entry = lsapsam_update_group_mapping_entry ;
( * pdb_method ) - > delete_group_mapping_entry = lsapsam_delete_group_mapping_entry ;
( * pdb_method ) - > enum_group_mapping = lsapsam_enum_group_mapping ;
2002-03-02 13:16:28 +03:00
/* TODO: Setup private data and free */
ldap_state = talloc_zero ( pdb_context - > mem_ctx , sizeof ( struct ldapsam_privates ) ) ;
if ( ! ldap_state ) {
DEBUG ( 0 , ( " talloc() failed for ldapsam private_data! \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
if ( location ) {
ldap_state - > uri = talloc_strdup ( pdb_context - > mem_ctx , location ) ;
2002-10-01 17:10:57 +04:00
# ifdef WITH_LDAP_SAMCONFIG
2002-03-02 13:16:28 +03:00
} else {
2002-10-01 17:10:57 +04:00
int ldap_port = lp_ldap_port ( ) ;
2002-11-02 06:47:48 +03:00
/* remap default port if not using SSL (ie clear or TLS) */
if ( ( lp_ldap_ssl ( ) ! = LDAP_SSL_ON ) & & ( ldap_port = = 636 ) ) {
2002-10-01 17:10:57 +04:00
ldap_port = 389 ;
}
2002-11-02 06:47:48 +03:00
ldap_state - > uri = talloc_asprintf ( pdb_context - > mem_ctx , " %s://%s:%d " , lp_ldap_ssl ( ) = = LDAP_SSL_ON ? " ldaps " : " ldap " , lp_ldap_server ( ) , ldap_port ) ;
2002-10-01 17:10:57 +04:00
if ( ! ldap_state - > uri ) {
return NT_STATUS_NO_MEMORY ;
}
# else
} else {
2002-11-02 06:47:48 +03:00
ldap_state - > uri = " ldap://localhost " ;
2002-10-01 17:10:57 +04:00
# endif
2002-03-02 13:16:28 +03:00
}
( * pdb_method ) - > private_data = ldap_state ;
( * pdb_method ) - > free_private_data = free_private_data ;
return NT_STATUS_OK ;
}
NTSTATUS pdb_init_ldapsam_nua ( PDB_CONTEXT * pdb_context , PDB_METHODS * * pdb_method , const char * location )
{
NTSTATUS nt_status ;
struct ldapsam_privates * ldap_state ;
uint32 low_nua_uid , high_nua_uid ;
if ( ! NT_STATUS_IS_OK ( nt_status = pdb_init_ldapsam ( pdb_context , pdb_method , location ) ) ) {
return nt_status ;
}
( * pdb_method ) - > name = " ldapsam_nua " ;
ldap_state = ( * pdb_method ) - > private_data ;
ldap_state - > permit_non_unix_accounts = True ;
if ( ! lp_non_unix_account_range ( & low_nua_uid , & high_nua_uid ) ) {
DEBUG ( 0 , ( " cannot use ldapsam_nua without 'non unix account range' in smb.conf! \n " ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
2002-07-15 14:35:28 +04:00
ldap_state - > low_nua_rid = fallback_pdb_uid_to_user_rid ( low_nua_uid ) ;
2002-03-02 13:16:28 +03:00
2002-07-15 14:35:28 +04:00
ldap_state - > high_nua_rid = fallback_pdb_uid_to_user_rid ( high_nua_uid ) ;
2002-03-02 13:16:28 +03:00
return NT_STATUS_OK ;
}
2001-09-26 00:21:21 +04:00
# else
2002-03-02 13:16:28 +03:00
NTSTATUS pdb_init_ldapsam ( PDB_CONTEXT * pdb_context , PDB_METHODS * * pdb_method , const char * location )
2001-09-26 00:21:21 +04:00
{
2002-07-15 14:35:28 +04:00
DEBUG ( 0 , ( " ldap not detected at configure time, ldapsam not availalble! \n " ) ) ;
2002-03-02 13:16:28 +03:00
return NT_STATUS_UNSUCCESSFUL ;
}
NTSTATUS pdb_init_ldapsam_nua ( PDB_CONTEXT * pdb_context , PDB_METHODS * * pdb_method , const char * location )
{
2002-07-15 14:35:28 +04:00
DEBUG ( 0 , ( " ldap not dectected at configure time, ldapsam_nua not available! \n " ) ) ;
2002-03-02 13:16:28 +03:00
return NT_STATUS_UNSUCCESSFUL ;
}
2001-09-26 00:21:21 +04:00
# endif