summaryrefslogtreecommitdiff
path: root/source3/passdb/sampassldap.c
diff options
context:
space:
mode:
authorLuke Leighton <lkcl@samba.org>1998-12-07 22:52:49 +0000
committerLuke Leighton <lkcl@samba.org>1998-12-07 22:52:49 +0000
commit4323fd4072854069eb9a3fe0dc0c33fb06b19335 (patch)
tree27b03928c278f59d336f2f1bec506c54b366ee2e /source3/passdb/sampassldap.c
parent656a7565e9beecc4a5be4e9ac62815d61548dd46 (diff)
downloadsamba-4323fd4072854069eb9a3fe0dc0c33fb06b19335.tar.gz
samba-4323fd4072854069eb9a3fe0dc0c33fb06b19335.tar.bz2
samba-4323fd4072854069eb9a3fe0dc0c33fb06b19335.zip
added ldap files by Matthew Chapman.
(This used to be commit 2bc031e8fafeafdc58c6a8056597b647d00657ae)
Diffstat (limited to 'source3/passdb/sampassldap.c')
-rw-r--r--source3/passdb/sampassldap.c433
1 files changed, 433 insertions, 0 deletions
diff --git a/source3/passdb/sampassldap.c b/source3/passdb/sampassldap.c
new file mode 100644
index 0000000000..1c3283df0f
--- /dev/null
+++ b/source3/passdb/sampassldap.c
@@ -0,0 +1,433 @@
+/*
+ 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 */
+LDAP *ldap_struct;
+LDAPMessage *ldap_results;
+LDAPMessage *ldap_entry;
+
+
+/*******************************************************************
+ NT name/RID search functions.
+ ******************************************************************/
+
+BOOL ldap_search_by_rid(uint32 rid)
+{
+ fstring filter;
+
+ slprintf(filter, sizeof(filter)-1,
+ "(&(rid=%d)(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 = atoi(temp);
+ 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;
+
+ 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 = atoi(temp);
+ 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;
+
+ 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, "%d", 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_open_connection(False))
+ return NULL;
+
+ ldap_search_for("objectclass=sambaAccount");
+
+ return ldap_struct;
+}
+
+static void ldapsam_enumclose(void *vp)
+{
+ ldap_close_connection();
+}
+
+
+/*************************************************************************
+ 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_open_connection(False))
+ return NULL;
+
+ ldap_search_by_ntname(name);
+ ret = ldapsam_getsam();
+
+ ldap_close_connection();
+ return ret;
+}
+
+static struct sam_passwd *ldapsam_getsambyuid(uid_t userid)
+{
+ struct sam_passwd *ret;
+
+ if(!ldap_open_connection(False))
+ return NULL;
+
+ ldap_search_by_uid(userid);
+ ret = ldapsam_getsam();
+
+ ldap_close_connection();
+ return ret;
+}
+
+static struct sam_passwd *ldapsam_getsambyrid(uint32 user_rid)
+{
+ struct sam_passwd *ret;
+
+ if(!ldap_open_connection(False))
+ return NULL;
+
+ ldap_search_by_rid(user_rid);
+ ret = ldapsam_getsam();
+
+ ldap_close_connection();
+ 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;
+
+ 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;
+
+ 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_open_connection(False))
+ return NULL;
+
+ ldap_search_by_ntname(name);
+ ret = ldapsam_getdispinfo();
+
+ ldap_close_connection();
+ return ret;
+}
+
+static struct sam_disp_info *ldapsam_getdispbyrid(uint32 user_rid)
+{
+ struct sam_disp_info *ret;
+
+ if(!ldap_open_connection(False))
+ return NULL;
+
+ ldap_search_by_rid(user_rid);
+ ret = ldapsam_getdispinfo();
+
+ ldap_close_connection();
+ 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