mirror of
https://github.com/samba-team/samba.git
synced 2024-12-28 07:21:54 +03:00
91c77f5432
* Added new APIs for modifying groups. * RIDs are allocated similarly to NT, starting from 1000 and incrementing by 1 for each new user/group. * RIDs are now consistently in hex * Fixed bugs reported by Allan Bjorklund <allan@umich.edu>: - ldap_close_connection is exported by OpenLDAP - changed to ldap_disconnect - Missing ldap_connect() in getusergroups functions - ldap_next_entry was being called too early while retrieving a sam_struct - LDAP globals should be extern in sampassldap.c * Fixed bugs reported by Martin Hofbauer <mh@bacher.at> - Newly added workstation trust accounts had attributes DU rather than W. - User dn's were forced to start with "uid=XX" rather than using the existing dn.
442 lines
11 KiB
C
442 lines
11 KiB
C
/*
|
|
Unix SMB/Netbios implementation.
|
|
Version 2.0.
|
|
LDAP protocol helper functions for SAMBA
|
|
Copyright (C) Matthew Chapman 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.
|
|
|
|
*/
|
|
|
|
#include "includes.h"
|
|
|
|
#ifdef WITH_LDAP
|
|
|
|
#include <lber.h>
|
|
#include <ldap.h>
|
|
|
|
extern int DEBUGLEVEL;
|
|
|
|
/* Internal state */
|
|
extern LDAP *ldap_struct;
|
|
extern LDAPMessage *ldap_results;
|
|
extern LDAPMessage *ldap_entry;
|
|
|
|
|
|
/*******************************************************************
|
|
NT name/RID search functions.
|
|
******************************************************************/
|
|
|
|
BOOL ldap_search_by_rid(uint32 rid)
|
|
{
|
|
fstring filter;
|
|
|
|
slprintf(filter, sizeof(filter)-1,
|
|
"(&(rid=%x)(objectclass=sambaAccount))", rid);
|
|
return ldap_search_for(filter);
|
|
}
|
|
|
|
BOOL ldap_search_by_ntname(const char *ntname)
|
|
{
|
|
fstring filter;
|
|
|
|
slprintf(filter, sizeof(filter)-1,
|
|
"(&(ntuid=%s)(objectclass=sambaAccount))", ntname);
|
|
return ldap_search_for(filter);
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
Store NTTIMEs as time_t's.
|
|
******************************************************************/
|
|
|
|
static void ldap_save_time(LDAPMod ***modlist, int modop, char *attribute,
|
|
NTTIME *nttime)
|
|
{
|
|
fstring tstr;
|
|
time_t t;
|
|
|
|
t = nt_time_to_unix(nttime);
|
|
|
|
if(t == -1)
|
|
return;
|
|
|
|
slprintf(tstr, sizeof(tstr)-1, "%08X", t);
|
|
ldap_make_mod(modlist, modop, attribute, tstr);
|
|
}
|
|
|
|
static void ldap_read_time(char *attribute, NTTIME *nttime)
|
|
{
|
|
fstring timestr;
|
|
time_t t;
|
|
|
|
if(ldap_get_attribute(attribute, timestr))
|
|
t = (time_t)strtol(timestr, NULL, 16);
|
|
else
|
|
t = (time_t)(-1);
|
|
|
|
unix_to_nt_time(nttime, t);
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
Contruct a sam_passwd structure.
|
|
******************************************************************/
|
|
|
|
static struct sam_passwd *ldapsam_getsam()
|
|
{
|
|
static pstring full_name;
|
|
static pstring acct_desc;
|
|
static pstring home_dir;
|
|
static pstring home_drive;
|
|
static pstring logon_script;
|
|
static pstring profile_path;
|
|
static pstring workstations;
|
|
pstring temp;
|
|
struct sam_passwd *sam21;
|
|
struct smb_passwd *smbpw;
|
|
|
|
if(!ldap_entry)
|
|
return NULL;
|
|
|
|
smbpw = ldap_getpw();
|
|
sam21 = pwdb_smb_to_sam(smbpw);
|
|
|
|
if(ldap_get_attribute("gidNumber", temp))
|
|
sam21->unix_gid = atoi(temp);
|
|
else
|
|
sam21->unix_gid = (gid_t)(-1);
|
|
|
|
if(ldap_get_attribute("grouprid", temp))
|
|
sam21->group_rid = strtol(temp, NULL, 16);
|
|
else
|
|
sam21->group_rid = 0xFFFFFFFF;
|
|
|
|
if(ldap_get_attribute("cn", full_name))
|
|
sam21->full_name = full_name;
|
|
else
|
|
sam21->full_name = NULL;
|
|
|
|
if(ldap_get_attribute("description", acct_desc))
|
|
sam21->acct_desc = acct_desc;
|
|
else
|
|
sam21->acct_desc = NULL;
|
|
|
|
if(ldap_get_attribute("smbHome", home_dir))
|
|
sam21->home_dir = home_dir;
|
|
else
|
|
sam21->home_dir = NULL;
|
|
|
|
if(ldap_get_attribute("homeDrive", home_drive))
|
|
sam21->dir_drive = home_drive;
|
|
else
|
|
sam21->dir_drive = NULL;
|
|
|
|
if(ldap_get_attribute("script", logon_script))
|
|
sam21->logon_script = logon_script;
|
|
else
|
|
sam21->logon_script = NULL;
|
|
|
|
if(ldap_get_attribute("profile", profile_path))
|
|
sam21->profile_path = profile_path;
|
|
else
|
|
sam21->profile_path = NULL;
|
|
|
|
if(ldap_get_attribute("workstations", workstations))
|
|
sam21->workstations = workstations;
|
|
else
|
|
sam21->workstations = NULL;
|
|
|
|
ldap_read_time("pwdCanChange", &sam21->pass_can_change_time);
|
|
ldap_read_time("pwdMustChange", &sam21->pass_must_change_time);
|
|
ldap_read_time("logonTime", &sam21->logon_time);
|
|
ldap_read_time("logoffTime", &sam21->logoff_time);
|
|
ldap_read_time("kickoffTime", &sam21->kickoff_time);
|
|
|
|
sam21->unknown_3 = 0xffffff; /* don't know */
|
|
sam21->logon_divs = 168; /* hours per week */
|
|
sam21->hours_len = 21; /* 21 times 8 bits = 168 */
|
|
memset(sam21->hours, 0xff, sam21->hours_len); /* all hours */
|
|
sam21->unknown_5 = 0x00020000; /* don't know */
|
|
sam21->unknown_6 = 0x000004ec; /* don't know */
|
|
sam21->unknown_str = NULL;
|
|
sam21->munged_dial = NULL;
|
|
|
|
ldap_entry = ldap_next_entry(ldap_struct, ldap_entry);
|
|
return sam21;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
Contruct a sam_disp_info structure.
|
|
******************************************************************/
|
|
|
|
static struct sam_disp_info *ldapsam_getdispinfo()
|
|
{
|
|
static struct sam_disp_info dispinfo;
|
|
static pstring nt_name;
|
|
static pstring full_name;
|
|
pstring temp;
|
|
|
|
if(!ldap_entry)
|
|
return NULL;
|
|
|
|
if(!ldap_get_attribute("ntuid", nt_name) &&
|
|
!ldap_get_attribute("uid", nt_name)) {
|
|
DEBUG(0,("Missing uid\n"));
|
|
return NULL; }
|
|
dispinfo.nt_name = nt_name;
|
|
|
|
DEBUG(2,("Retrieving account [%s]\n",nt_name));
|
|
|
|
if(ldap_get_attribute("rid", temp))
|
|
dispinfo.user_rid = strtol(temp, NULL, 16);
|
|
else {
|
|
DEBUG(0,("Missing rid\n"));
|
|
return NULL; }
|
|
|
|
if(ldap_get_attribute("cn", full_name))
|
|
dispinfo.full_name = full_name;
|
|
else
|
|
dispinfo.full_name = NULL;
|
|
|
|
ldap_entry = ldap_next_entry(ldap_struct, ldap_entry);
|
|
return &dispinfo;
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
Queues the necessary modifications to save a sam_passwd structure
|
|
************************************************************************/
|
|
|
|
static void ldapsam_sammods(struct sam_passwd *newpwd, LDAPMod ***mods,
|
|
int operation)
|
|
{
|
|
struct smb_passwd *smbpw;
|
|
pstring temp;
|
|
|
|
smbpw = pwdb_sam_to_smb(newpwd);
|
|
ldap_smbpwmods(smbpw, mods, operation);
|
|
|
|
slprintf(temp, sizeof(temp)-1, "%d", newpwd->unix_gid);
|
|
ldap_make_mod(mods, operation, "gidNumber", temp);
|
|
|
|
slprintf(temp, sizeof(temp)-1, "%x", newpwd->group_rid);
|
|
ldap_make_mod(mods, operation, "grouprid", temp);
|
|
|
|
ldap_make_mod(mods, operation, "cn", newpwd->full_name);
|
|
ldap_make_mod(mods, operation, "description", newpwd->acct_desc);
|
|
ldap_make_mod(mods, operation, "smbHome", newpwd->home_dir);
|
|
ldap_make_mod(mods, operation, "homeDrive", newpwd->dir_drive);
|
|
ldap_make_mod(mods, operation, "script", newpwd->logon_script);
|
|
ldap_make_mod(mods, operation, "profile", newpwd->profile_path);
|
|
ldap_make_mod(mods, operation, "workstations", newpwd->workstations);
|
|
|
|
ldap_save_time(mods, operation, "pwdCanChange",
|
|
&newpwd->pass_can_change_time);
|
|
ldap_save_time(mods, operation, "pwdMustChange",
|
|
&newpwd->pass_must_change_time);
|
|
ldap_save_time(mods, operation, "logonTime",
|
|
&newpwd->logon_time);
|
|
ldap_save_time(mods, operation, "logoffTime",
|
|
&newpwd->logoff_time);
|
|
ldap_save_time(mods, operation, "kickoffTime",
|
|
&newpwd->kickoff_time);
|
|
}
|
|
|
|
|
|
/***************************************************************
|
|
Begin/end account enumeration.
|
|
****************************************************************/
|
|
|
|
static void *ldapsam_enumfirst(BOOL update)
|
|
{
|
|
if (!ldap_connect())
|
|
return NULL;
|
|
|
|
ldap_search_for("objectclass=sambaAccount");
|
|
|
|
return ldap_struct;
|
|
}
|
|
|
|
static void ldapsam_enumclose(void *vp)
|
|
{
|
|
ldap_disconnect();
|
|
}
|
|
|
|
|
|
/*************************************************************************
|
|
Save/restore the current position in a query
|
|
*************************************************************************/
|
|
|
|
static SMB_BIG_UINT ldapsam_getdbpos(void *vp)
|
|
{
|
|
return (SMB_BIG_UINT)((ulong)ldap_entry);
|
|
}
|
|
|
|
static BOOL ldapsam_setdbpos(void *vp, SMB_BIG_UINT tok)
|
|
{
|
|
ldap_entry = (LDAPMessage *)((ulong)tok);
|
|
return (True);
|
|
}
|
|
|
|
|
|
/*************************************************************************
|
|
Return sam_passwd information.
|
|
*************************************************************************/
|
|
|
|
static struct sam_passwd *ldapsam_getsambynam(const char *name)
|
|
{
|
|
struct sam_passwd *ret;
|
|
|
|
if(!ldap_connect())
|
|
return NULL;
|
|
|
|
ldap_search_by_ntname(name);
|
|
ret = ldapsam_getsam();
|
|
|
|
ldap_disconnect();
|
|
return ret;
|
|
}
|
|
|
|
static struct sam_passwd *ldapsam_getsambyuid(uid_t userid)
|
|
{
|
|
struct sam_passwd *ret;
|
|
|
|
if(!ldap_connect())
|
|
return NULL;
|
|
|
|
ldap_search_by_uid(userid);
|
|
ret = ldapsam_getsam();
|
|
|
|
ldap_disconnect();
|
|
return ret;
|
|
}
|
|
|
|
static struct sam_passwd *ldapsam_getsambyrid(uint32 user_rid)
|
|
{
|
|
struct sam_passwd *ret;
|
|
|
|
if(!ldap_connect())
|
|
return NULL;
|
|
|
|
ldap_search_by_rid(user_rid);
|
|
ret = ldapsam_getsam();
|
|
|
|
ldap_disconnect();
|
|
return ret;
|
|
}
|
|
|
|
static struct sam_passwd *ldapsam_getcurrentsam(void *vp)
|
|
{
|
|
return ldapsam_getsam();
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
Modify user information given a sam_passwd struct.
|
|
*************************************************************************/
|
|
|
|
static BOOL ldapsam_addsam(struct sam_passwd *newpwd)
|
|
{
|
|
LDAPMod **mods;
|
|
|
|
if (!newpwd || !ldap_allocaterid(&newpwd->user_rid))
|
|
return (False);
|
|
|
|
ldapsam_sammods(newpwd, &mods, LDAP_MOD_ADD);
|
|
return ldap_makemods("uid", newpwd->unix_name, mods, True);
|
|
}
|
|
|
|
static BOOL ldapsam_modsam(struct sam_passwd *pwd, BOOL override)
|
|
{
|
|
LDAPMod **mods;
|
|
|
|
if (!pwd)
|
|
return (False);
|
|
|
|
ldapsam_sammods(pwd, &mods, LDAP_MOD_REPLACE);
|
|
return ldap_makemods("uid", pwd->unix_name, mods, False);
|
|
}
|
|
|
|
|
|
/*************************************************************************
|
|
Return sam_disp_info information.
|
|
*************************************************************************/
|
|
|
|
static struct sam_disp_info *ldapsam_getdispbynam(const char *name)
|
|
{
|
|
struct sam_disp_info *ret;
|
|
|
|
if(!ldap_connect())
|
|
return NULL;
|
|
|
|
ldap_search_by_ntname(name);
|
|
ret = ldapsam_getdispinfo();
|
|
|
|
ldap_disconnect();
|
|
return ret;
|
|
}
|
|
|
|
static struct sam_disp_info *ldapsam_getdispbyrid(uint32 user_rid)
|
|
{
|
|
struct sam_disp_info *ret;
|
|
|
|
if(!ldap_connect())
|
|
return NULL;
|
|
|
|
ldap_search_by_rid(user_rid);
|
|
ret = ldapsam_getdispinfo();
|
|
|
|
ldap_disconnect();
|
|
return ret;
|
|
}
|
|
|
|
static struct sam_disp_info *ldapsam_getcurrentdisp(void *vp)
|
|
{
|
|
return ldapsam_getdispinfo();
|
|
}
|
|
|
|
|
|
|
|
static struct sam_passdb_ops ldapsam_ops =
|
|
{
|
|
ldapsam_enumfirst,
|
|
ldapsam_enumclose,
|
|
ldapsam_getdbpos,
|
|
ldapsam_setdbpos,
|
|
|
|
ldapsam_getsambynam,
|
|
ldapsam_getsambyuid,
|
|
ldapsam_getsambyrid,
|
|
ldapsam_getcurrentsam,
|
|
ldapsam_addsam,
|
|
ldapsam_modsam,
|
|
|
|
ldapsam_getdispbynam,
|
|
ldapsam_getdispbyrid,
|
|
ldapsam_getcurrentdisp
|
|
};
|
|
|
|
struct sam_passdb_ops *ldap_initialise_sam_password_db(void)
|
|
{
|
|
return &ldapsam_ops;
|
|
}
|
|
|
|
#else
|
|
void sampassldap_dummy_function(void);
|
|
void sampassldap_dummy_function(void) { } /* stop some compilers complaining */
|
|
#endif
|