summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/includes.h5
-rw-r--r--source3/include/proto.h20
-rw-r--r--source3/param/loadparm.c29
-rw-r--r--source3/passdb/ldap.c563
-rw-r--r--source3/passdb/smbpass.c9
-rw-r--r--source3/rpc_server/srv_ldap_helpers.c162
-rw-r--r--source3/rpc_server/srv_samr.c126
7 files changed, 859 insertions, 55 deletions
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 5fc2811981..859603c29f 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -1212,6 +1212,11 @@ extern char *sys_errlist[];
#define MAXCODEPAGELINES 256
#endif
+#ifdef USE_LDAP
+#include "lber.h"
+#include "ldap.h"
+#endif
+
/***** automatically generated prototypes *****/
#include "proto.h"
diff --git a/source3/include/proto.h b/source3/include/proto.h
index fc41d18a1d..720806026b 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -840,6 +840,14 @@ void make_wks_r_query_info(WKS_R_QUERY_INFO *r_u,
int status) ;
void wks_io_r_query_info(char *desc, WKS_R_QUERY_INFO *r_u, prs_struct *ps, int depth);
+/*The following definitions come from lib/rpc/server/srv_ldap_helpers.c */
+
+BOOL get_ldap_entries(SAM_USER_INFO_21 *pw_buf,
+ int *total_entries, int *num_entries,
+ int max_num_entries,
+ uint16 acb_mask, int switch_level);
+BOOL ldap_get_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid);
+
/*The following definitions come from lib/rpc/server/srv_lsa.c */
BOOL api_ntlsa_rpc(pipes_struct *p, prs_struct *data);
@@ -952,6 +960,11 @@ char *lp_domain_admin_users(void);
char *lp_domain_guest_users(void);
char *lp_domain_hostsallow(void);
char *lp_domain_hostsdeny(void);
+char *lp_ldap_server(void);
+char *lp_ldap_suffix(void);
+char *lp_ldap_filter(void);
+char *lp_ldap_root(void);
+char *lp_ldap_rootpasswd(void);
BOOL lp_dns_proxy(void);
BOOL lp_wins_support(void);
BOOL lp_we_are_a_wins_server(void);
@@ -1005,6 +1018,7 @@ int lp_client_code_page(void);
int lp_announce_as(void);
int lp_lm_announce(void);
int lp_lm_interval(void);
+int lp_ldap_port(void);
char *lp_preexec(int );
char *lp_postexec(int );
char *lp_rootpreexec(int );
@@ -1547,14 +1561,14 @@ BOOL pm_process( char *FileName,
void generate_next_challenge(char *challenge);
BOOL set_challenge(char *challenge);
-BOOL last_challenge(char *challenge);
+BOOL last_challenge(unsigned char *challenge);
user_struct *get_valid_user_struct(uint16 vuid);
void invalidate_vuid(uint16 vuid);
char *validated_username(uint16 vuid);
int setup_groups(char *user, int uid, int gid, int *p_ngroups,
int **p_igroups, gid_t **p_groups,
int **p_attrs);
-uint16 register_vuid(int uid,int gid, char *name,BOOL guest);
+uint16 register_vuid(int uid,int gid, char *unix_name, char *requested_name, BOOL guest);
void add_session_user(char *user);
BOOL update_smbpassword_file( char *user, fstring password);
void dfs_unlogin(void);
@@ -1726,7 +1740,7 @@ int reply_lanman2(char *outbuf);
int reply_nt1(char *outbuf);
void close_cnum(int cnum, uint16 vuid);
void exit_server(char *reason);
-void standard_sub(int cnum,char *str);
+void standard_sub(int cnum,char *str,uint16 vuid);
char *smb_fn_name(int type);
int chain_reply(char *inbuf,char *outbuf,int size,int bufsize);
int construct_reply(char *inbuf,char *outbuf,int size,int bufsize);
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index cbb17adc95..7483af54a4 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -144,6 +144,11 @@ typedef struct
char *szDomainGroups;
char *szDriverFile;
char *szNameResolveOrder;
+ char *szLdapServer;
+ char *szLdapSuffix;
+ char *szLdapFilter;
+ char *szLdapRoot;
+ char *szLdapRootPassword;
int max_log_size;
int mangled_stack;
int max_xmit;
@@ -167,6 +172,7 @@ typedef struct
int shmem_size;
int client_code_page;
int announce_as; /* This is initialised in init_globals */
+ int ldap_port;
BOOL bDNSproxy;
BOOL bWINSsupport;
BOOL bWINSproxy;
@@ -616,6 +622,16 @@ static struct parm_struct parm_table[] =
{"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_GLOBAL},
{"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, 0},
+ {"Ldap Options", P_SEP, P_SEPARATOR},
+ {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0},
+ {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0},
+ {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, 0},
+ {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, 0},
+ {"ldap root", P_STRING, P_GLOBAL, &Globals.szLdapRoot, NULL, NULL, 0},
+ {"ldap root passwd", P_STRING, P_GLOBAL, &Globals.szLdapRootPassword,NULL, NULL, 0},
+
+
+
{"Miscellaneous Options", P_SEP, P_SEPARATOR},
{"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL, 0},
{"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
@@ -760,6 +776,11 @@ static void init_globals(void)
Globals.bUnixPasswdSync = False;
Globals.bPasswdChatDebug = False;
+ /* default values for ldap */
+ string_set(&Globals.szLdapServer, "localhost");
+ Globals.ldap_port=389;
+
+
/* these parameters are set to defaults that are more appropriate
for the increasing samba install base:
@@ -962,6 +983,12 @@ FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers)
FN_GLOBAL_STRING(lp_domain_hostsallow,&Globals.szDomainHostsallow)
FN_GLOBAL_STRING(lp_domain_hostsdeny,&Globals.szDomainHostsdeny)
+FN_GLOBAL_STRING(lp_ldap_server,&Globals.szLdapServer);
+FN_GLOBAL_STRING(lp_ldap_suffix,&Globals.szLdapSuffix);
+FN_GLOBAL_STRING(lp_ldap_filter,&Globals.szLdapFilter);
+FN_GLOBAL_STRING(lp_ldap_root,&Globals.szLdapRoot);
+FN_GLOBAL_STRING(lp_ldap_rootpasswd,&Globals.szLdapRootPassword);
+
FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport)
@@ -1017,6 +1044,8 @@ FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce)
FN_GLOBAL_INTEGER(lp_lm_interval,&Globals.lm_interval)
+FN_GLOBAL_INTEGER(lp_ldap_port,&Globals.ldap_port)
+
FN_LOCAL_STRING(lp_preexec,szPreExec)
FN_LOCAL_STRING(lp_postexec,szPostExec)
FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
diff --git a/source3/passdb/ldap.c b/source3/passdb/ldap.c
new file mode 100644
index 0000000000..fedc31cbfc
--- /dev/null
+++ b/source3/passdb/ldap.c
@@ -0,0 +1,563 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ LDAP protocol helper functions for SAMBA
+ Copyright (C) Jean François Micouleau 1998
+
+ 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 02139, USA.
+
+*/
+
+#ifdef USE_LDAP
+
+#include "includes.h"
+#include "lber.h"
+#include "ldap.h"
+
+extern int DEBUGLEVEL;
+
+/*******************************************************************
+ open a connection to the ldap serve.
+******************************************************************/
+BOOL ldap_open_connection(LDAP **ldap_struct)
+{
+ if ( (*ldap_struct = ldap_open(lp_ldap_server(),lp_ldap_port()) )== NULL)
+ {
+ DEBUG(0,("%s: The LDAP server is not responding !\n",timestring()));
+ return(False);
+ }
+ DEBUG(2,("ldap_open_connection: connection opened\n"));
+ return (True);
+}
+
+
+/*******************************************************************
+ connect anonymously to the ldap server.
+ FIXME: later (jfm)
+******************************************************************/
+static BOOL ldap_connect_anonymous(LDAP *ldap_struct)
+{
+ if ( ldap_simple_bind_s(ldap_struct,lp_ldap_root(),lp_ldap_rootpasswd()) != LDAP_SUCCESS)
+ {
+ DEBUG(0,("%s: Couldn't bind to the LDAP server !\n", timestring() ));
+ return(False);
+ }
+ return (True);
+}
+
+
+/*******************************************************************
+ connect to the ldap server under system privileg.
+******************************************************************/
+BOOL ldap_connect_system(LDAP *ldap_struct)
+{
+ if ( ldap_simple_bind_s(ldap_struct,lp_ldap_root(),lp_ldap_rootpasswd()) != LDAP_SUCCESS)
+ {
+ DEBUG(0,("%s: Couldn't bind to the LDAP server !\n", timestring() ));
+ return(False);
+ }
+ DEBUG(2,("ldap_connect_system: succesfull connection to the LDAP server\n"));
+ return (True);
+}
+
+/*******************************************************************
+ connect to the ldap server under a particular user.
+******************************************************************/
+static BOOL ldap_connect_user(LDAP *ldap_struct, char *user, char *password)
+{
+ if ( ldap_simple_bind_s(ldap_struct,lp_ldap_root(),lp_ldap_rootpasswd()) != LDAP_SUCCESS)
+ {
+ DEBUG(0,("%s: Couldn't bind to the LDAP server !\n", timestring() ));
+ return(False);
+ }
+ DEBUG(2,("ldap_connect_user: succesfull connection to the LDAP server\n"));
+ return (True);
+}
+
+/*******************************************************************
+ run the search by name.
+******************************************************************/
+static BOOL ldap_search_one_user(LDAP *ldap_struct, char *filter, LDAPMessage **result)
+{
+ int scope = LDAP_SCOPE_ONELEVEL;
+ int rc;
+
+ DEBUG(2,("ldap_search_one_user: searching for:[%s]\n", filter));
+
+ rc=ldap_search_s(ldap_struct, lp_ldap_suffix(), scope, filter, NULL, 0, result);
+
+ if (rc != LDAP_SUCCESS )
+ {
+ DEBUG(0,("%s: Problem during the LDAP search\n",timestring()));
+ return(False);
+ }
+ return (True);
+}
+
+/*******************************************************************
+ run the search by name.
+******************************************************************/
+BOOL ldap_search_one_user_by_name(LDAP *ldap_struct, char *user, LDAPMessage **result)
+{
+ pstring filter;
+ /*
+ in the filter expression, replace %u with the real name
+ so in ldap filter, %u MUST exist :-)
+ */
+ strcpy(filter,lp_ldap_filter());
+ string_sub(filter,"%u",user);
+
+ if ( !ldap_search_one_user(ldap_struct, filter, result) )
+ {
+ return(False);
+ }
+ return (True);
+}
+
+/*******************************************************************
+ run the search by uid.
+******************************************************************/
+BOOL ldap_search_one_user_by_uid(LDAP *ldap_struct, int uid, LDAPMessage **result)
+{
+ pstring filter;
+ /*
+ in the filter expression, replace %u with the real name
+ so in ldap filter, %u MUST exist :-)
+ */
+ snprintf(filter, sizeof(pstring), "uidAccount=%d", uid);
+
+ if ( !ldap_search_one_user(ldap_struct, filter, result) )
+ {
+ return(False);
+ }
+ return (True);
+}
+
+/*******************************************************************
+ search an attribute and return the first value found.
+******************************************************************/
+void get_single_attribute(LDAP *ldap_struct, LDAPMessage *entry, char *attribute, char *value)
+{
+ char **valeurs;
+
+ if ( (valeurs=ldap_get_values(ldap_struct, entry, attribute)) != NULL)
+ {
+ strcpy(value, valeurs[0]);
+ ldap_value_free(valeurs);
+ DEBUG(3,("get_single_attribute: [%s]=[%s]\n", attribute, value));
+ }
+ else
+ {
+ value=NULL;
+ }
+}
+
+/*******************************************************************
+ find a user or a machine return a smbpass struct.
+******************************************************************/
+struct passwd *Get_ldap_Pwnam(char *user)
+{
+ LDAP *ldap_struct;
+ LDAPMessage *result;
+ LDAPMessage *entry;
+ char **valeur;
+ BOOL machine=False;
+ BOOL sambaAccount=False;
+ int i;
+
+ static struct passwd ldap_passwd;
+ static char pw_name[256];
+ static char pw_passwd[256];
+ static char pw_gecos[256];
+ static char pw_dir[256];
+ static char pw_shell[256];
+ ldap_passwd.pw_name=pw_name;
+ ldap_passwd.pw_passwd=pw_passwd;
+ ldap_passwd.pw_gecos=pw_gecos;
+ ldap_passwd.pw_dir=pw_dir;
+ ldap_passwd.pw_shell=pw_shell;
+
+ DEBUG(0,("XXXX XXXX XXXX, ca merde serieux!\n"));
+
+ /* first clear the struct */
+ bzero(pw_name,sizeof(pw_name));
+ bzero(pw_passwd,sizeof(pw_passwd));
+ bzero(pw_gecos,sizeof(pw_gecos));
+ bzero(pw_dir,sizeof(pw_dir));
+ bzero(pw_shell,sizeof(pw_shell));
+ ldap_passwd.pw_uid=-1;
+ ldap_passwd.pw_gid=-1;
+
+
+ ldap_open_connection(&ldap_struct);
+
+ /*
+ to get all the attributes (specially the userPassword )
+ we have to connect under the system administrator account
+ */
+ ldap_connect_system(ldap_struct);
+
+ ldap_search_one_user(ldap_struct, user, &result);
+
+ if (ldap_count_entries(ldap_struct, result) != 1)
+ {
+ DEBUG(0,("%s: Strange %d user in the base!\n",
+ timestring(), ldap_count_entries(ldap_struct, result) ));
+ return(False);
+ }
+ /* take the first and unique entry */
+ entry=ldap_first_entry(ldap_struct, result);
+
+ /* check what kind of account it is */
+ /* as jeremy doesn't want to split getpwnam in 2 functions :-( */
+
+ if (user[strlen(user)-1]=='$')
+ {
+ machine=True;
+ }
+
+ if (!machine)
+ {
+ valeur=ldap_get_values(ldap_struct,entry, "objectclass");
+
+ /* check if the entry is a person objectclass*/
+ if (valeur!=NULL)
+ for (i=0;valeur[i]!=NULL;i++)
+ {
+ if (!strcmp(valeur[i],"sambaAccount")) sambaAccount=True;
+ }
+ ldap_value_free(valeur);
+
+ if (sambaAccount)
+ {
+ /* we should have enough info to fill the struct */
+ strncpy(ldap_passwd.pw_name,user,strlen(user));
+
+ valeur=ldap_get_values(ldap_struct,entry, "uidAccount");
+ if (valeur != NULL)
+ {
+ ldap_passwd.pw_uid=atoi(valeur[0]);
+ }
+ ldap_value_free(valeur);
+
+ valeur=ldap_get_values(ldap_struct,entry, "gidAccount");
+ if (valeur != NULL)
+ {
+ ldap_passwd.pw_gid=atoi(valeur[0]);
+ }
+ ldap_value_free(valeur);
+
+ valeur=ldap_get_values(ldap_struct,entry, "userPassword");
+ if (valeur != NULL)
+ {
+ /*
+ as we have the clear-text password, we have to crypt it !
+ hum hum hum currently pass the clear text password to wait
+ */
+ strncpy(ldap_passwd.pw_passwd,valeur[0],strlen(valeur[0]));
+ }
+ ldap_value_free(valeur);
+
+ valeur=ldap_get_values(ldap_struct,entry, "gecos");
+ if (valeur != NULL)
+ {
+ strncpy(ldap_passwd.pw_gecos,valeur[0],strlen(valeur[0]));
+ }
+ ldap_value_free(valeur);
+
+ valeur=ldap_get_values(ldap_struct,entry, "homeDirectory");
+ if (valeur != NULL)
+ {
+ strncpy(ldap_passwd.pw_dir,valeur[0],strlen(valeur[0]));
+ }
+ ldap_value_free(valeur);
+
+ valeur=ldap_get_values(ldap_struct,entry, "loginShell");
+ if (valeur != NULL)
+ {
+ strncpy(ldap_passwd.pw_shell,valeur[0],strlen(valeur[0]));
+ }
+ ldap_value_free(valeur);
+ }
+ }
+ else
+ {
+ }
+
+ ldap_unbind(ldap_struct);
+}
+
+/*******************************************************************
+ check if the returned entry is a sambaAccount objectclass.
+******************************************************************/
+BOOL ldap_check_user(LDAP *ldap_struct, LDAPMessage *entry)
+{
+ BOOL sambaAccount=False;
+ char **valeur;
+ int i;
+
+ DEBUG(2,("ldap_check_user: "));
+ valeur=ldap_get_values(ldap_struct, entry, "objectclass");
+ if (valeur!=NULL)
+ {
+ for (i=0;valeur[i]!=NULL;i++)
+ {
+ if (!strcmp(valeur[i],"sambaAccount")) sambaAccount=True;
+ }
+ }
+ DEBUG(2,("%s\n",sambaAccount?"yes":"no"));
+ ldap_value_free(valeur);
+ return (sambaAccount);
+}
+
+/*******************************************************************
+ check if the returned entry is a sambaMachine objectclass.
+******************************************************************/
+BOOL ldap_check_machine(LDAP *ldap_struct, LDAPMessage *entry)
+{
+ BOOL sambaMachine=False;
+ char **valeur;
+ int i;
+
+ DEBUG(2,("ldap_check_machine: "));
+ valeur=ldap_get_values(ldap_struct, entry, "objectclass");
+ if (valeur!=NULL)
+ {
+ for (i=0;valeur[i]!=NULL;i++)
+ {
+ if (!strcmp(valeur[i],"sambaMachine")) sambaMachine=True;
+ }
+ }
+ DEBUG(2,("%s\n",sambaMachine?"yes":"no"));
+ ldap_value_free(valeur);
+ return (sambaMachine);
+}
+
+/*******************************************************************
+ retrieve the user's info and contruct a smb_passwd structure.
+******************************************************************/
+static void ldap_get_user(LDAP *ldap_struct,LDAPMessage *entry,
+ struct smb_passwd *ldap_passwd)
+{
+ static pstring user_name;
+ static unsigned char smbpwd[16];
+ static unsigned char smbntpwd[16];
+ char **valeur;
+
+ get_single_attribute(ldap_struct, entry, "cn", user_name);
+
+ DEBUG(2,("ldap_get_user: user: %s\n",user_name));
+
+ if ( (valeur=ldap_get_values(ldap_struct, entry, "uidAccount")) != NULL)
+ {
+ ldap_passwd->smb_userid=atoi(valeur[0]);
+ ldap_value_free(valeur);
+ }
+
+ if ( (valeur=ldap_get_values(ldap_struct, entry, "userPassword")) != NULL)
+ {
+ memset(smbntpwd, '\0', 16);
+ E_md4hash((uchar *) valeur[0], smbntpwd);
+ valeur[0][14] = '\0';
+ strupper(valeur[0]);
+ memset(smbpwd, '\0', 16);
+ E_P16((uchar *) valeur[0], smbpwd);
+ ldap_value_free(valeur);
+ }
+
+ if ( (valeur=ldap_get_values(ldap_struct,entry, "userAccountControl") ) != NULL)
+ {
+ ldap_passwd->acct_ctrl=atoi(valeur[0]);
+ if (ldap_passwd->acct_ctrl & (ACB_DOMTRUST|ACB_WSTRUST|ACB_SVRTRUST) )
+ {
+ DEBUG(0,("Inconsistency in the LDAP database\n"));
+
+ }
+ if (ldap_passwd->acct_ctrl & ACB_NORMAL)
+ {
+ ldap_passwd->smb_name=user_name;
+ ldap_passwd->smb_passwd=smbpwd;
+ ldap_passwd->smb_nt_passwd=smbntpwd;
+ }
+ ldap_value_free(valeur);
+ }
+
+ if ( (valeur=ldap_get_values(ldap_struct,entry, "pwdLastSet")) != NULL)
+ {
+ ldap_passwd->last_change_time=(time_t)strtol(valeur[0], NULL, 16);
+ ldap_value_free(valeur);
+ }
+}
+
+/*************************************************************
+ Routine to get the next 32 hex characters and turn them
+ into a 16 byte array.
+**************************************************************/
+
+static int gethexpwd(char *p, char *pwd)
+{
+ int i;
+ unsigned char lonybble, hinybble;
+ char *hexchars = "0123456789ABCDEF";
+ char *p1, *p2;
+
+ for (i = 0; i < 32; i += 2) {
+ hinybble = toupper(p[i]);
+ lonybble = toupper(p[i + 1]);
+
+ p1 = strchr(hexchars, hinybble);
+ p2 = strchr(hexchars, lonybble);
+ if (!p1 || !p2)
+ return (False);
+ hinybble = PTR_DIFF(p1, hexchars);
+ lonybble = PTR_DIFF(p2, hexchars);
+
+ pwd[i / 2] = (hinybble << 4) | lonybble;
+ }
+ return (True);
+}
+
+/*******************************************************************
+ retrieve the machine's info and contruct a smb_passwd structure.
+******************************************************************/
+static void ldap_get_machine(LDAP *ldap_struct,LDAPMessage *entry,
+ struct smb_passwd *ldap_passwd)
+{
+ static pstring user_name;
+ static unsigned char smbntpwd[16];
+ char **valeur;
+
+ /* by default it's a station */
+ ldap_passwd->acct_ctrl = ACB_WSTRUST;
+
+ get_single_attribute(ldap_struct, entry, "cn", user_name);
+ DEBUG(2,("ldap_get_machine: machine: %s\n", user_name));
+
+ if ( (valeur=ldap_get_values(ldap_struct, entry, "uidAccount")) != NULL)
+ {
+ ldap_passwd->smb_userid=atoi(valeur[0]);
+ ldap_value_free(valeur);
+ }
+
+ if ( (valeur=ldap_get_values(ldap_struct, entry, "machinePassword")) != NULL)
+ {
+ gethexpwd(valeur[0],smbntpwd);
+ ldap_value_free(valeur);
+ }
+
+ if ( (valeur=ldap_get_values(ldap_struct,entry, "machineRole") ) != NULL)
+ {
+ if ( !strcmp(valeur[0],"workstation") )
+ ldap_passwd->acct_ctrl=ACB_WSTRUST;
+ else
+ if ( !strcmp(valeur[0],"server") )
+ ldap_passwd->acct_ctrl=ACB_SVRTRUST;
+ ldap_value_free(valeur);
+ }
+
+ ldap_passwd->smb_name=user_name;
+ ldap_passwd->smb_passwd=smbntpwd;
+ ldap_passwd->smb_nt_passwd=smbntpwd;
+}
+
+/*******************************************************************
+ find a user or a machine return a smbpass struct.
+******************************************************************/
+struct smb_passwd *ldap_get_smbpwd_entry(char *name, int smb_userid)
+{
+ LDAP *ldap_struct;
+ LDAPMessage *result;
+ LDAPMessage *entry;
+ BOOL machine=False;
+
+ static struct smb_passwd ldap_passwd;
+
+ ldap_passwd.smb_name = NULL;
+ ldap_passwd.smb_passwd = NULL;
+ ldap_passwd.smb_nt_passwd = NULL;
+
+ ldap_passwd.smb_userid = -1;
+ ldap_passwd.acct_ctrl = ACB_DISABLED;
+ ldap_passwd.last_change_time = 0;
+
+ ldap_struct=NULL;
+
+ if (name != NULL)
+ {
+ DEBUG(10, ("ldap_get_smbpwd_entry: search by name: %s\n", name));
+ }
+ else
+ {
+ DEBUG(10, ("ldap_get_smbpwd_entry: search by smb_userid: %x\n", smb_userid));
+ }
+
+ if (!ldap_open_connection(&ldap_struct))
+ return (NULL);
+ if (!ldap_connect_system(ldap_struct))
+ return (NULL);
+
+ if (name != NULL)
+ {
+ if (!ldap_search_one_user_by_name(ldap_struct, name, &result))
+ return (NULL);
+ }
+ else
+ {
+ if (!ldap_search_one_user_by_uid(ldap_struct, smb_userid, &result))
+ return (NULL);
+ }
+
+ if (ldap_count_entries(ldap_struct, result) == 0)
+ {
+ DEBUG(2,("%s: Non existant user!\n", timestring() ));
+ return (NULL);
+ }
+
+ if (ldap_count_entries(ldap_struct, result) > 1)
+ {
+ DEBUG(2,("%s: Strange %d users in the base!\n",
+ timestring(), ldap_count_entries(ldap_struct, result) ));
+ }
+ /* take the first and unique entry */
+ entry=ldap_first_entry(ldap_struct, result);
+
+ if (name != NULL)
+ {
+ DEBUG(0,("ldap_get_smbpwd_entry: Found user: %s\n",name));
+
+ if (name[strlen(name)-1]=='$')
+ machine=True;
+ else
+ machine=False;
+ }
+
+ if (machine==False)
+ {
+ if (ldap_check_user(ldap_struct, entry)==True)
+ ldap_get_user(ldap_struct, entry, &ldap_passwd);
+ }
+ else
+ {
+ if (ldap_check_machine(ldap_struct, entry)==True)
+ ldap_get_machine(ldap_struct, entry, &ldap_passwd);
+ }
+
+ ldap_msgfree(result);
+ result=NULL;
+ ldap_unbind(ldap_struct);
+
+ return(&ldap_passwd);
+}
+#endif
diff --git a/source3/passdb/smbpass.c b/source3/passdb/smbpass.c
index 72e3c3035e..cb3a4a9a99 100644
--- a/source3/passdb/smbpass.c
+++ b/source3/passdb/smbpass.c
@@ -554,7 +554,11 @@ static struct smb_passwd *get_smbpwd_entry(char *name, int smb_userid)
struct smb_passwd *getsmbpwnam(char *name)
{
+#ifdef USE_LDAP
+ return ldap_get_smbpwd_entry(name, 0);
+#else
return get_smbpwd_entry(name, 0);
+#endif /* USE_LDAP */
}
/************************************************************************
@@ -563,7 +567,11 @@ struct smb_passwd *getsmbpwnam(char *name)
struct smb_passwd *getsmbpwuid(unsigned int uid)
{
+#ifdef USE_LDAP
+ return ldap_get_smbpwd_entry(NULL, uid);
+#else
return get_smbpwd_entry(NULL, uid);
+#endif /* USE_LDAP */
}
/**********************************************************
@@ -673,6 +681,7 @@ Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
sprintf((char *)&p[i*2], "%02X", newpwd->smb_passwd[i]);
}
} else {
+ i=0;
if(newpwd->acct_ctrl & ACB_PWNOTREQ)
sprintf(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
else
diff --git a/source3/rpc_server/srv_ldap_helpers.c b/source3/rpc_server/srv_ldap_helpers.c
new file mode 100644
index 0000000000..d1c091c6c9
--- /dev/null
+++ b/source3/rpc_server/srv_ldap_helpers.c
@@ -0,0 +1,162 @@
+#ifdef USE_LDAP
+
+#include "includes.h"
+#include "lber.h"
+#include "ldap.h"
+
+extern int DEBUGLEVEL;
+
+/*******************************************************************
+ find a user or a machine return a smbpass struct.
+******************************************************************/
+static void make_ldap_sam_user_info_21(LDAP *ldap_struct, LDAPMessage *entry, SAM_USER_INFO_21 *user)
+{
+ pstring cn;
+ pstring fullname;
+ pstring home_dir;
+ pstring dir_drive;
+ pstring logon_script;
+ pstring profile_path;
+ pstring acct_desc;
+ pstring workstations;
+ pstring temp;
+
+ if (ldap_check_user(ldap_struct, entry)==True)
+ {
+ get_single_attribute(ldap_struct, entry, "cn", cn);
+ get_single_attribute(ldap_struct, entry, "userFullName", fullname);
+ get_single_attribute(ldap_struct, entry, "homeDirectory", home_dir);
+ get_single_attribute(ldap_struct, entry, "homeDrive", dir_drive);
+ get_single_attribute(ldap_struct, entry, "scriptPath", logon_script);
+ get_single_attribute(ldap_struct, entry, "profilePath", profile_path);
+ get_single_attribute(ldap_struct, entry, "comment", acct_desc);
+ get_single_attribute(ldap_struct, entry, "userWorkstations", workstations);
+
+ get_single_attribute(ldap_struct, entry, "rid", temp);
+ user->user_rid=atoi(temp);
+ get_single_attribute(ldap_struct, entry, "primaryGroupID", temp);
+ user->group_rid=atoi(temp);
+ get_single_attribute(ldap_struct, entry, "controlAccessRights", temp);
+ user->acb_info=atoi(temp);
+
+ make_unistr2(&(user->uni_user_name), cn, strlen(cn));
+ make_uni_hdr(&(user->hdr_user_name), strlen(cn), strlen(cn), 1);
+ make_unistr2(&(user->uni_full_name), fullname, strlen(fullname));
+ make_uni_hdr(&(user->hdr_full_name), strlen(fullname), strlen(fullname), 1);
+ make_unistr2(&(user->uni_home_dir), home_dir, strlen(home_dir));
+ make_uni_hdr(&(user->hdr_home_dir), strlen(home_dir), strlen(home_dir), 1);
+ make_unistr2(&(user->uni_dir_drive), dir_drive, strlen(dir_drive));
+ make_uni_hdr(&(user->hdr_dir_drive), strlen(dir_drive), strlen(dir_drive), 1);
+ make_unistr2(&(user->uni_logon_script), logon_script, strlen(logon_script));
+ make_uni_hdr(&(user->hdr_logon_script), strlen(logon_script), strlen(logon_script), 1);
+ make_unistr2(&(user->uni_profile_path), profile_path, strlen(profile_path));
+ make_uni_hdr(&(user->hdr_profile_path), strlen(profile_path), strlen(profile_path), 1);
+ make_unistr2(&(user->uni_acct_desc), acct_desc, strlen(acct_desc));
+ make_uni_hdr(&(user->hdr_acct_desc), strlen(acct_desc), strlen(acct_desc), 1);
+ make_unistr2(&(user->uni_workstations), workstations, strlen(workstations));
+ make_uni_hdr(&(user->hdr_workstations), strlen(workstations), strlen(workstations), 1);
+ }
+}
+
+/*******************************************************************
+ find a user or a machine return a smbpass struct.
+******************************************************************/
+BOOL get_ldap_entries(SAM_USER_INFO_21 *pw_buf,
+ int *total_entries, int *num_entries,
+ int max_num_entries,
+ uint16 acb_mask, int switch_level)
+{
+ LDAP *ldap_struct;
+ LDAPMessage *result;
+ LDAPMessage *entry;
+
+ int scope = LDAP_SCOPE_ONELEVEL;
+ int rc;
+
+ char filter[256];
+
+ (*num_entries) = 0;
+ (*total_entries) = 0;
+
+ if (!ldap_open_connection(&ldap_struct)) /* open a connection to the server */
+ return (False);
+
+ if (!ldap_connect_system(ldap_struct)) /* connect as system account */
+ return (False);
+
+
+ /* when the class is known the search is much faster */
+ switch (switch_level)
+ {
+ case 1: strcpy(filter, "objectclass=sambaAccount");
+ break;
+ case 2: strcpy(filter, "objectclass=sambaMachine");
+ break;
+ default: strcpy(filter, "(|(objectclass=sambaMachine)(objectclass=sambaAccount))");
+ break;
+ }
+
+ rc=ldap_search_s(ldap_struct, lp_ldap_suffix(), scope, filter, NULL, 0, &result);
+
+ DEBUG(2,("%d entries in the base!\n", ldap_count_entries(ldap_struct, result) ));
+
+ for ( entry = ldap_first_entry(ldap_struct, result);
+ (entry != NULL) && (*num_entries) < max_num_entries;
+ entry = ldap_next_entry(ldap_struct, entry) )
+ {
+ make_ldap_sam_user_info_21(ldap_struct, entry, &(pw_buf[(*num_entries)]) );
+
+ if (acb_mask == 0 || IS_BITS_SET_SOME(pw_buf[(*num_entries)].acb_info, acb_mask))
+ {
+ DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
+ (*num_entries)++;
+ }
+ else
+ {
+ DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
+ }
+
+ (*total_entries)++;
+ }
+
+ ldap_msgfree(result);
+ ldap_unbind(ldap_struct);
+ return (*num_entries) > 0;
+}
+
+BOOL ldap_get_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
+{
+ LDAP *ldap_struct;
+ LDAPMessage *result;
+ LDAPMessage *entry;
+
+ if (!ldap_open_connection(&ldap_struct))
+ return (False);
+ if (!ldap_connect_system(ldap_struct))
+ return (False);
+
+ if (!ldap_search_one_user_by_uid(ldap_struct, rid, &result))
+ return (False);
+
+ if (ldap_count_entries(ldap_struct, result) == 0)
+ {
+ DEBUG(2,("%s: Non existant user!\n", timestring() ));
+ return (False);
+ }
+
+ if (ldap_count_entries(ldap_struct, result) > 1)
+ {
+ DEBUG(2,("%s: Strange %d users in the base!\n",
+ timestring(), ldap_count_entries(ldap_struct, result) ));
+ }
+ /* take the first and unique entry */
+ entry=ldap_first_entry(ldap_struct, result);
+
+ make_ldap_sam_user_info_21(ldap_struct, entry, id21);
+
+ ldap_msgfree(result);
+ ldap_unbind(ldap_struct);
+ return(True);
+}
+
+#endif
diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c
index 162d9c45d0..aa240ad3c6 100644
--- a/source3/rpc_server/srv_samr.c
+++ b/source3/rpc_server/srv_samr.c
@@ -45,55 +45,55 @@ static BOOL get_smbpwd_entries(SAM_USER_INFO_21 *pw_buf,
{
void *vp = NULL;
struct smb_passwd *pwd = NULL;
-
- (*num_entries) = 0;
- (*total_entries) = 0;
-
- if (pw_buf == NULL) return False;
-
- vp = startsmbpwent(False);
- if (!vp)
- {
- DEBUG(0, ("get_smbpwd_entries: Unable to open SMB password file.\n"));
- return False;
- }
-
- while (((pwd = getsmbpwent(vp)) != NULL) && (*num_entries) < max_num_entries)
- {
- int user_name_len = strlen(pwd->smb_name);
- make_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->smb_name, user_name_len);
- make_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len,
- user_name_len, 1);
- pw_buf[(*num_entries)].user_rid = pwd->smb_userid;
- bzero( pw_buf[(*num_entries)].nt_pwd , 16);
-
- /* Now check if the NT compatible password is available. */
- if (pwd->smb_nt_passwd != NULL)
- {
- memcpy( pw_buf[(*num_entries)].nt_pwd , pwd->smb_nt_passwd, 16);
- }
-
- pw_buf[(*num_entries)].acb_info = (uint16)pwd->acct_ctrl;
-
- DEBUG(5, ("get_smbpwd_entries: idx: %d user %s, uid %d, acb %x",
- (*num_entries), pwd->smb_name, pwd->smb_userid, pwd->acct_ctrl));
-
- if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask))
- {
- DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
- (*num_entries)++;
- }
- else
- {
- DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
- }
-
- (*total_entries)++;
- }
-
- endsmbpwent(vp);
-
- return (*num_entries) > 0;
+
+ (*num_entries) = 0;
+ (*total_entries) = 0;
+
+ if (pw_buf == NULL) return False;
+
+ vp = startsmbpwent(False);
+ if (!vp)
+ {
+ DEBUG(0, ("get_smbpwd_entries: Unable to open SMB password file.\n"));
+ return False;
+ }
+
+ while (((pwd = getsmbpwent(vp)) != NULL) && (*num_entries) < max_num_entries)
+ {
+ int user_name_len = strlen(pwd->smb_name);
+ make_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->smb_name, user_name_len-1);
+ make_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len-1,
+ user_name_len-1, 1);
+ pw_buf[(*num_entries)].user_rid = pwd->smb_userid;
+ bzero( pw_buf[(*num_entries)].nt_pwd , 16);
+
+ /* Now check if the NT compatible password is available. */
+ if (pwd->smb_nt_passwd != NULL)
+ {
+ memcpy( pw_buf[(*num_entries)].nt_pwd , pwd->smb_nt_passwd, 16);
+ }
+
+ pw_buf[(*num_entries)].acb_info = (uint16)pwd->acct_ctrl;
+
+ DEBUG(5, ("get_smbpwd_entries: idx: %d user %s, uid %d, acb %x",
+ (*num_entries), pwd->smb_name, pwd->smb_userid, pwd->acct_ctrl));
+
+ if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask))
+ {
+ DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
+ (*num_entries)++;
+ }
+ else
+ {
+ DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
+ }
+
+ (*total_entries)++;
+ }
+
+ endsmbpwent(vp);
+
+ return (*num_entries) > 0;
}
/*******************************************************************
@@ -463,33 +463,52 @@ static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u,
DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
+#ifndef USE_LDAP
become_root(True);
got_pwds = get_smbpwd_entries(pass, &total_entries, &num_entries, MAX_SAM_ENTRIES, 0);
unbecome_root(True);
+#endif
switch (q_u->switch_level)
{
case 0x1:
{
+
/* query disp info is for users */
+ switch_level = 0x1;
+#ifdef USE_LDAP
+ got_pwds = get_ldap_entries(pass,
+ &total_entries,
+ &num_entries,
+ MAX_SAM_ENTRIES,
+ 0,
+ switch_level);
+#endif
make_sam_info_1(&info1, ACB_NORMAL,
q_u->start_idx, num_entries, pass);
ctr.sam.info1 = &info1;
- switch_level = 0x1;
break;
}
case 0x2:
{
/* query disp info is for servers */
+ switch_level = 0x2;
+#ifdef USE_LDAP
+ got_pwds = get_ldap_entries(pass,
+ &total_entries,
+ &num_entries,
+ MAX_SAM_ENTRIES,
+ 0,
+ switch_level);
+#endif
make_sam_info_2(&info2, ACB_WSTRUST,
q_u->start_idx, num_entries, pass);
ctr.sam.info2 = &info2;
- switch_level = 0x2;
break;
}
@@ -1025,8 +1044,11 @@ static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
case 21:
{
info = (void*)&id21;
+#ifdef USE_LDAP
+ status = ldap_get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
+#else
status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
-
+#endif
break;
}