jean-francois micouleau's well-alpha code for ldap password database stuff!
authorLuke Leighton <lkcl@samba.org>
Wed, 6 May 1998 17:43:44 +0000 (17:43 +0000)
committerLuke Leighton <lkcl@samba.org>
Wed, 6 May 1998 17:43:44 +0000 (17:43 +0000)
he's going to hate me for checking this in so early, but...

source/include/includes.h
source/include/proto.h
source/param/loadparm.c
source/passdb/ldap.c [new file with mode: 0644]
source/passdb/smbpass.c
source/rpc_server/srv_ldap_helpers.c [new file with mode: 0644]
source/rpc_server/srv_samr.c

index 5fc281198199a17d45b96749dd17668819c0b961..859603c29f50eb9171fa6343c46d14eac2fdfefb 100644 (file)
@@ -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"
 
index fc41d18a1db6e2985f31f4b3d6c3dab6e459349c..720806026b3758c71cf8001bcf5dc3dcf4fdeed4 100644 (file)
@@ -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);
index cbb17adc9563cf846ad72449f36afa065599e372..7483af54a452462ebebcce9ec4e432244c3462e9 100644 (file)
@@ -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/source/passdb/ldap.c b/source/passdb/ldap.c
new file mode 100644 (file)
index 0000000..fedc31c
--- /dev/null
@@ -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
index 72e3c3035e0e611c9ed683afda0791734fd1bb4f..cb3a4a9a992bb74890f4f709314f6719743b096d 100644 (file)
@@ -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/source/rpc_server/srv_ldap_helpers.c b/source/rpc_server/srv_ldap_helpers.c
new file mode 100644 (file)
index 0000000..d1c091c
--- /dev/null
@@ -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
index 162d9c45d01e153ff5d0c409473dc044d06f148f..aa240ad3c6fa887ca08f5ad30c73f1441177a669 100644 (file)
@@ -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;
                        }