summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/LDAP/samba.schema10
-rw-r--r--source3/Makefile.in12
-rw-r--r--source3/configure.in12
-rw-r--r--source3/include/includes.h4
-rw-r--r--source3/include/smbldap.h101
-rw-r--r--source3/lib/smbldap.c259
-rw-r--r--source3/passdb/pdb_ldap.c285
-rw-r--r--source3/sam/idmap_ldap.c446
8 files changed, 646 insertions, 483 deletions
diff --git a/examples/LDAP/samba.schema b/examples/LDAP/samba.schema
index 3db7094bf2..9887954045 100644
--- a/examples/LDAP/samba.schema
+++ b/examples/LDAP/samba.schema
@@ -315,3 +315,13 @@ objectclass ( 1.3.6.1.4.1.7165.2.2.5 NAME 'sambaDomain' SUP top STRUCTURAL
MUST ( sambaDomainName $ sambaNextGroupRid $ sambaNextUserRid $
sambaSID ) )
+## used for idmap_ldap module
+objectclass ( 1.3.6.1.4.1.7165.1.2.2.7 NAME 'sambaUnixIdPool' SUP top AUXILIARY
+ DESC 'Pool for allocating UNIX uids/gids'
+ MUST ( uidNumber $ gidNumber ) )
+
+objectclass ( 1.3.6.1.4.1.7165.1.2.2.8 NAME 'sambaIdmapEntry' SUP top STRUCTURAL
+ DESC 'Mapping from a SID to an ID'
+ MUST ( sambaSID )
+ MAY ( uidNumber $ gidNumber ))
+
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 945953fe48..df66f6a724 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -158,6 +158,8 @@ MODULES = $(VFS_MODULES) $(PDB_MODULES) $(RPC_MODULES) $(IDMAP_MODULES) $(CHARSE
TDBBASE_OBJ = tdb/tdb.o tdb/spinlock.o
TDB_OBJ = $(TDBBASE_OBJ) tdb/tdbutil.o
+SMBLDAP_OBJ = @SMBLDAP@
+
LIB_OBJ = lib/charcnv.o lib/debug.o lib/fault.o \
lib/getsmbpass.o lib/interface.o lib/md4.o \
lib/interfaces.o lib/pidfile.o lib/replace.o \
@@ -178,7 +180,7 @@ LIB_OBJ = lib/charcnv.o lib/debug.o lib/fault.o \
lib/adt_tree.o lib/gencache.o $(TDB_OBJ) \
lib/module.o lib/ldap_escape.o @CHARSET_STATIC@
-LIB_SMBD_OBJ = lib/system_smbd.o lib/util_smbd.o
+LIB_SMBD_OBJ = lib/system_smbd.o lib/util_smbd.o
READLINE_OBJ = lib/readline.o
@@ -277,13 +279,13 @@ PASSDB_GET_SET_OBJ = passdb/pdb_get_set.o
PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \
passdb/machine_sid.o passdb/util_sam_sid.o passdb/pdb_compat.o \
- passdb/privileges.o @PDB_STATIC@
+ passdb/privileges.o @PDB_STATIC@ $(SMBLDAP__OBJ)
XML_OBJ = passdb/pdb_xml.o
MYSQL_OBJ = passdb/pdb_mysql.o
DEVEL_HELP_OBJ = modules/weird.o
-IDMAP_OBJ = sam/idmap.o sam/idmap_util.o @IDMAP_STATIC@
+IDMAP_OBJ = sam/idmap.o sam/idmap_util.o @IDMAP_STATIC@ $(SMBLDAP_OBJ)
GROUPDB_OBJ = groupdb/mapping.o
@@ -387,7 +389,7 @@ SWAT_OBJ1 = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \
SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(LIBSMB_OBJ) \
$(LOCKING_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(KRBCLIENT_OBJ) \
$(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \
- $(POPT_LIB_OBJ) $(IDMAP_OBJ)
+ $(POPT_LIB_OBJ) $(IDMAP_OBJ)
SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o \
$(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
@@ -597,7 +599,7 @@ WINBINDD_OBJ = \
$(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
$(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \
$(PROFILE_OBJ) $(UNIGRP_OBJ) $(IDMAP_OBJ) \
- $(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ)
+ $(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ)
WBINFO_OBJ = nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \
$(UBIQX_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
diff --git a/source3/configure.in b/source3/configure.in
index 79f01ba421..53b4f1524f 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -2302,8 +2302,8 @@ AC_ARG_WITH(ldap,
AC_MSG_RESULT($with_ldap_support)
if test x"$with_ldap_support" = x"yes"; then
-ac_save_LIBS="$LIBS"
-LIBS=""
+ ac_save_LIBS="$LIBS"
+ LIBS=""
##################################################################
# we might need the lber lib on some systems. To avoid link errors
@@ -2322,6 +2322,9 @@ LIBS=""
])
])
+ ## we have ldap so build the list of files for the generic samba ldap library
+ SMBLDAP="lib/smbldap.o"
+
########################################################
# If we have LDAP, does it's rebind procedure take 2 or 3 arguments?
# Check found in pam_ldap 145.
@@ -2334,8 +2337,9 @@ LIBS=""
AC_CHECK_FUNCS(ldap_initialize)
fi
-LDAP_LIBS="$LIBS";
-LIBS="$ac_save_LIBS";
+ AC_SUBST(SMBLDAP)
+ LDAP_LIBS="$LIBS";
+ LIBS="$ac_save_LIBS";
else
# Can't have ADS support without LDAP
if test x"$with_ads_support" = x"yes"; then
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 4de81c46d2..ac5c48d780 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -869,6 +869,10 @@ struct printjob;
struct smb_ldap_privates;
+/* forward declarations from smbldap.c */
+
+#include "smbldap.h"
+
/***** automatically generated prototypes *****/
#ifndef NO_PROTO_H
#include "proto.h"
diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h
new file mode 100644
index 0000000000..13451fa24f
--- /dev/null
+++ b/source3/include/smbldap.h
@@ -0,0 +1,101 @@
+/*
+ Unix SMB/CIFS mplementation.
+ LDAP protocol helper functions for SAMBA
+ Copyright (C) Gerald Carter 2001-2003
+
+ 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.
+
+*/
+
+#ifndef _SMBLDAP_H
+#define _SMBLDAP_H
+
+/* specify schema versions between 2.2. and 3.0 */
+
+#define SCHEMAVER_SAMBAACCOUNT 1
+#define SCHEMAVER_SAMBASAMACCOUNT 2
+
+/* objectclass names */
+
+#define LDAP_OBJ_SAMBASAMACCOUNT "sambaSamAccount"
+#define LDAP_OBJ_SAMBAACCOUNT "sambaAccount"
+#define LDAP_OBJ_GROUPMAP "sambaGroupMapping"
+#define LDAP_OBJ_DOMINFO "sambaDomain"
+#define LDAP_OBJ_IDPOOL "sambaUnixIdPool"
+#define LDAP_OBJ_IDMAP_ENTRY "sambaIdmapEntry"
+
+#define LDAP_OBJ_ACCOUNT "account"
+#define LDAP_OBJ_POSIXACCOUNT "posixAccount"
+#define LDAP_OBJ_POSIXGROUP "posixGroup"
+
+/* some generic attributes that get reused a lot */
+
+#define LDAP_ATTRIBUTE_SID "sambaSID"
+#define LDAP_ATTRIBUTE_UIDNUMBER "uidNumber"
+#define LDAP_ATTRIBUTE_GIDNUMBER "gidNumber"
+
+/* attribute map table indexes */
+
+#define LDAP_ATTR_LIST_END 0
+#define LDAP_ATTR_UID 1
+#define LDAP_ATTR_UIDNUMBER 2
+#define LDAP_ATTR_GIDNUMBER 3
+#define LDAP_ATTR_UNIX_HOME 4
+#define LDAP_ATTR_PWD_LAST_SET 5
+#define LDAP_ATTR_PWD_CAN_CHANGE 6
+#define LDAP_ATTR_PWD_MUST_CHANGE 7
+#define LDAP_ATTR_LOGON_TIME 8
+#define LDAP_ATTR_LOGOFF_TIME 9
+#define LDAP_ATTR_KICKOFF_TIME 10
+#define LDAP_ATTR_CN 11
+#define LDAP_ATTR_DISPLAY_NAME 12
+#define LDAP_ATTR_HOME_PATH 13
+#define LDAP_ATTR_LOGON_SCRIPT 14
+#define LDAP_ATTR_PROFILE_PATH 15
+#define LDAP_ATTR_DESC 16
+#define LDAP_ATTR_USER_WKS 17
+#define LDAP_ATTR_USER_SID 18
+#define LDAP_ATTR_USER_RID 18
+#define LDAP_ATTR_PRIMARY_GROUP_SID 19
+#define LDAP_ATTR_PRIMARY_GROUP_RID 20
+#define LDAP_ATTR_LMPW 21
+#define LDAP_ATTR_NTPW 22
+#define LDAP_ATTR_DOMAIN 23
+#define LDAP_ATTR_OBJCLASS 24
+#define LDAP_ATTR_ACB_INFO 25
+#define LDAP_ATTR_NEXT_USERRID 26
+#define LDAP_ATTR_NEXT_GROUPRID 27
+#define LDAP_ATTR_DOM_SID 28
+#define LDAP_ATTR_HOME_DRIVE 29
+#define LDAP_ATTR_GROUP_SID 30
+#define LDAP_ATTR_GROUP_TYPE 31
+
+
+typedef struct _attrib_map_entry {
+ int attrib;
+ const char *name;
+} ATTRIB_MAP_ENTRY;
+
+/* structures */
+
+extern ATTRIB_MAP_ENTRY attrib_map_v22[];
+extern ATTRIB_MAP_ENTRY attrib_map_v30[];
+extern ATTRIB_MAP_ENTRY dominfo_attr_list[];
+extern ATTRIB_MAP_ENTRY groupmap_attr_list[];
+extern ATTRIB_MAP_ENTRY groupmap_attr_list_to_delete[];
+extern ATTRIB_MAP_ENTRY idpool_attr_list[];
+extern ATTRIB_MAP_ENTRY sidmap_attr_list[];
+
+#endif /* _SMBLDAP_H */
diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c
new file mode 100644
index 0000000000..5dbea0669f
--- /dev/null
+++ b/source3/lib/smbldap.c
@@ -0,0 +1,259 @@
+/*
+ Unix SMB/CIFS mplementation.
+ LDAP protocol helper functions for SAMBA
+ Copyright (C) Gerald Carter 2001-2003
+
+ 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"
+#include "smbldap.h"
+
+/* attributes used by Samba 2.2 */
+
+ATTRIB_MAP_ENTRY attrib_map_v22[] = {
+ { LDAP_ATTR_UID, "uid" },
+ { LDAP_ATTR_UIDNUMBER, LDAP_ATTRIBUTE_UIDNUMBER},
+ { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER},
+ { LDAP_ATTR_UNIX_HOME, "homeDirectory" },
+ { LDAP_ATTR_PWD_LAST_SET, "pwdLastSet" },
+ { LDAP_ATTR_PWD_CAN_CHANGE, "pwdCanChange" },
+ { LDAP_ATTR_PWD_MUST_CHANGE, "pwdMustChange" },
+ { LDAP_ATTR_LOGON_TIME, "logonTime" },
+ { LDAP_ATTR_LOGOFF_TIME, "logoffTime" },
+ { LDAP_ATTR_KICKOFF_TIME, "kickoffTime" },
+ { LDAP_ATTR_CN, "cn" },
+ { LDAP_ATTR_DISPLAY_NAME, "displayName" },
+ { LDAP_ATTR_HOME_PATH, "smbHome" },
+ { LDAP_ATTR_HOME_DRIVE, "homeDrives" },
+ { LDAP_ATTR_LOGON_SCRIPT, "scriptPath" },
+ { LDAP_ATTR_PROFILE_PATH, "profilePath" },
+ { LDAP_ATTR_DESC, "description" },
+ { LDAP_ATTR_USER_WKS, "userWorkstations"},
+ { LDAP_ATTR_USER_RID, "rid" },
+ { LDAP_ATTR_PRIMARY_GROUP_RID, "primaryGroupID"},
+ { LDAP_ATTR_LMPW, "lmPassword" },
+ { LDAP_ATTR_NTPW, "ntPassword" },
+ { LDAP_ATTR_DOMAIN, "domain" },
+ { LDAP_ATTR_OBJCLASS, "objectClass" },
+ { LDAP_ATTR_ACB_INFO, "acctFlags" },
+ { LDAP_ATTR_LIST_END, NULL }
+};
+
+/* attributes used by Samba 3.0's sambaSamAccount */
+
+ATTRIB_MAP_ENTRY attrib_map_v30[] = {
+ { LDAP_ATTR_UID, "uid" },
+ { LDAP_ATTR_UIDNUMBER, LDAP_ATTRIBUTE_UIDNUMBER},
+ { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER},
+ { LDAP_ATTR_UNIX_HOME, "homeDirectory" },
+ { LDAP_ATTR_PWD_LAST_SET, "sambaPwdLastSet" },
+ { LDAP_ATTR_PWD_CAN_CHANGE, "sambaPwdCanChange" },
+ { LDAP_ATTR_PWD_MUST_CHANGE, "sambaPwdMustChange" },
+ { LDAP_ATTR_LOGON_TIME, "sambaLogonTime" },
+ { LDAP_ATTR_LOGOFF_TIME, "sambaLogoffTime" },
+ { LDAP_ATTR_KICKOFF_TIME, "sambaKickoffTime" },
+ { LDAP_ATTR_CN, "cn" },
+ { LDAP_ATTR_DISPLAY_NAME, "displayName" },
+ { LDAP_ATTR_HOME_DRIVE, "sambaHomeDrive" },
+ { LDAP_ATTR_HOME_PATH, "sambaHomePath" },
+ { LDAP_ATTR_LOGON_SCRIPT, "sambaLogonScript" },
+ { LDAP_ATTR_PROFILE_PATH, "sambaProfilePath" },
+ { LDAP_ATTR_DESC, "description" },
+ { LDAP_ATTR_USER_WKS, "sambaUserWorkstations" },
+ { LDAP_ATTR_USER_SID, "sambaSID" },
+ { LDAP_ATTR_PRIMARY_GROUP_SID, "sambaPrimaryGroupSID" },
+ { LDAP_ATTR_LMPW, "sambaLMPassword" },
+ { LDAP_ATTR_NTPW, "sambaNTPassword" },
+ { LDAP_ATTR_DOMAIN, "sambaDomainName" },
+ { LDAP_ATTR_OBJCLASS, "objectClass" },
+ { LDAP_ATTR_ACB_INFO, "sambaAcctFlags" },
+ { LDAP_ATTR_LIST_END, NULL }
+};
+
+/* attributes used for alalocating RIDs */
+
+ATTRIB_MAP_ENTRY dominfo_attr_list[] = {
+ { LDAP_ATTR_DOMAIN, "sambaDomainName" },
+ { LDAP_ATTR_NEXT_USERRID, "sambaNextUserRid" },
+ { LDAP_ATTR_NEXT_GROUPRID, "sambaNextGroupRid" },
+ { LDAP_ATTR_DOM_SID, "sambaSID" },
+ { LDAP_ATTR_LIST_END, NULL },
+};
+
+/* Samba 3.0 group mapping attributes */
+
+ATTRIB_MAP_ENTRY groupmap_attr_list[] = {
+ { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER},
+ { LDAP_ATTR_GROUP_SID, "sambaSID" },
+ { LDAP_ATTR_GROUP_TYPE, "sambaGroupType" },
+ { LDAP_ATTR_DESC, "description" },
+ { LDAP_ATTR_DISPLAY_NAME, "displayName" },
+ { LDAP_ATTR_CN, "cn" },
+ { LDAP_ATTR_LIST_END, NULL }
+};
+
+ATTRIB_MAP_ENTRY groupmap_attr_list_to_delete[] = {
+ { LDAP_ATTR_GROUP_SID, "sambaSID" },
+ { LDAP_ATTR_GROUP_TYPE, "sambaGroupType" },
+ { LDAP_ATTR_DESC, "description" },
+ { LDAP_ATTR_DISPLAY_NAME, "displayName" },
+ { LDAP_ATTR_LIST_END, NULL }
+};
+
+/* idmap_ldap samba[U|G]idPool */
+
+ATTRIB_MAP_ENTRY idpool_attr_list[] = {
+ { LDAP_ATTR_UIDNUMBER, LDAP_ATTRIBUTE_UIDNUMBER},
+ { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER},
+ { LDAP_ATTR_LIST_END, NULL }
+};
+
+ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
+ { LDAP_ATTR_GROUP_SID, "sambaSID" },
+ { LDAP_ATTR_UIDNUMBER, LDAP_ATTRIBUTE_UIDNUMBER},
+ { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER},
+ { LDAP_ATTR_LIST_END, NULL }
+};
+
+/**********************************************************************
+ perform a simple table lookup and return the attribute name
+ **********************************************************************/
+
+const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key )
+{
+ int i = 0;
+
+ while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
+ if ( table[i].attrib == key )
+ return table[i].name;
+ i++;
+ }
+
+ return NULL;
+}
+
+
+/**********************************************************************
+ Return the list of attribute names from a mapping table
+ **********************************************************************/
+
+char** get_attr_list( ATTRIB_MAP_ENTRY table[] )
+{
+ char **names;
+ int i = 0;
+
+ while ( table[i].attrib != LDAP_ATTR_LIST_END )
+ i++;
+ i++;
+
+ names = (char**)malloc( sizeof(char*)*i );
+ if ( !names ) {
+ DEBUG(0,("get_attr_list: out of memory\n"));
+ return NULL;
+ }
+
+ i = 0;
+ while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
+ names[i] = strdup( table[i].name );
+ i++;
+ }
+ names[i] = NULL;
+
+ return names;
+}
+
+/*********************************************************************
+ Cleanup
+ ********************************************************************/
+
+void free_attr_list( char **list )
+{
+ int i = 0;
+
+ if ( !list )
+ return;
+
+ while ( list[i] )
+ SAFE_FREE( list[i] );
+
+ SAFE_FREE( list );
+}
+
+/*******************************************************************
+ find the ldap password
+******************************************************************/
+BOOL fetch_ldap_pw(char **dn, char** pw)
+{
+ char *key = NULL;
+ size_t size;
+
+ *dn = smb_xstrdup(lp_ldap_admin_dn());
+
+ if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
+ SAFE_FREE(*dn);
+ DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
+ }
+
+ *pw=secrets_fetch(key, &size);
+ SAFE_FREE(key);
+
+ if (!size) {
+ /* Upgrade 2.2 style entry */
+ char *p;
+ char* old_style_key = strdup(*dn);
+ char *data;
+ fstring old_style_pw;
+
+ if (!old_style_key) {
+ DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
+ return False;
+ }
+
+ for (p=old_style_key; *p; p++)
+ if (*p == ',') *p = '/';
+
+ data=secrets_fetch(old_style_key, &size);
+ if (!size && size < sizeof(old_style_pw)) {
+ DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
+ SAFE_FREE(old_style_key);
+ SAFE_FREE(*dn);
+ return False;
+ }
+
+ strncpy(old_style_pw, data, size);
+ old_style_pw[size] = 0;
+
+ SAFE_FREE(data);
+
+ if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
+ DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
+ SAFE_FREE(old_style_key);
+ SAFE_FREE(*dn);
+ return False;
+ }
+ if (!secrets_delete(old_style_key)) {
+ DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
+ }
+
+ SAFE_FREE(old_style_key);
+
+ *pw = smb_xstrdup(old_style_pw);
+ }
+
+ return True;
+}
+
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
index fb63e81d28..e6fd12fd0e 100644
--- a/source3/passdb/pdb_ldap.c
+++ b/source3/passdb/pdb_ldap.c
@@ -59,6 +59,8 @@
#define SAM_ACCOUNT struct sam_passwd
#endif
+#include "smbldap.h"
+
struct ldapsam_privates {
/* Former statics */
LDAP *ldap_struct;
@@ -93,177 +95,6 @@ struct ldapsam_privates {
static struct ldapsam_privates *static_ldap_state;
-/* specify schema versions between 2.2. and 3.0 */
-
-#define SCHEMAVER_SAMBAACCOUNT 1
-#define SCHEMAVER_SAMBASAMACCOUNT 2
-
-/* objectclass names */
-
-#define LDAP_OBJ_SAMBASAMACCOUNT "sambaSamAccount"
-#define LDAP_OBJ_SAMBAACCOUNT "sambaAccount"
-#define LDAP_OBJ_GROUPMAP "sambaGroupMapping"
-#define LDAP_OBJ_DOMINFO "sambaDomain"
-
-#define LDAP_OBJ_ACCOUNT "account"
-#define LDAP_OBJ_POSIXACCOUNT "posixAccount"
-#define LDAP_OBJ_POSIXGROUP "posixGroup"
-
-/* some generic attributes that get reused a lot */
-
-#define LDAP_ATTRIBUTE_SID "sambaSID"
-
-/* attribute map table indexes */
-
-#define LDAP_ATTR_LIST_END 0
-#define LDAP_ATTR_UID 1
-#define LDAP_ATTR_UIDNUMBER 2
-#define LDAP_ATTR_GIDNUMBER 3
-#define LDAP_ATTR_UNIX_HOME 4
-#define LDAP_ATTR_PWD_LAST_SET 5
-#define LDAP_ATTR_PWD_CAN_CHANGE 6
-#define LDAP_ATTR_PWD_MUST_CHANGE 7
-#define LDAP_ATTR_LOGON_TIME 8
-#define LDAP_ATTR_LOGOFF_TIME 9
-#define LDAP_ATTR_KICKOFF_TIME 10
-#define LDAP_ATTR_CN 11
-#define LDAP_ATTR_DISPLAY_NAME 12
-#define LDAP_ATTR_HOME_PATH 13
-#define LDAP_ATTR_LOGON_SCRIPT 14
-#define LDAP_ATTR_PROFILE_PATH 15
-#define LDAP_ATTR_DESC 16
-#define LDAP_ATTR_USER_WKS 17
-#define LDAP_ATTR_USER_SID 18
-#define LDAP_ATTR_USER_RID 18
-#define LDAP_ATTR_PRIMARY_GROUP_SID 19
-#define LDAP_ATTR_PRIMARY_GROUP_RID 20
-#define LDAP_ATTR_LMPW 21
-#define LDAP_ATTR_NTPW 22
-#define LDAP_ATTR_DOMAIN 23
-#define LDAP_ATTR_OBJCLASS 24
-#define LDAP_ATTR_ACB_INFO 25
-#define LDAP_ATTR_NEXT_USERRID 26
-#define LDAP_ATTR_NEXT_GROUPRID 27
-#define LDAP_ATTR_DOM_SID 28
-#define LDAP_ATTR_HOME_DRIVE 29
-#define LDAP_ATTR_GROUP_SID 30
-#define LDAP_ATTR_GROUP_TYPE 31
-
-
-typedef struct _attrib_map_entry {
- int attrib;
- const char *name;
-} ATTRIB_MAP_ENTRY;
-
-
-/* attributes used by Samba 2.2 */
-
-static ATTRIB_MAP_ENTRY attrib_map_v22[] = {
- { LDAP_ATTR_UID, "uid" },
- { LDAP_ATTR_UIDNUMBER, "uidNumber" },
- { LDAP_ATTR_GIDNUMBER, "gidNumber" },
- { LDAP_ATTR_UNIX_HOME, "homeDirectory" },
- { LDAP_ATTR_PWD_LAST_SET, "pwdLastSet" },
- { LDAP_ATTR_PWD_CAN_CHANGE, "pwdCanChange" },
- { LDAP_ATTR_PWD_MUST_CHANGE, "pwdMustChange" },
- { LDAP_ATTR_LOGON_TIME, "logonTime" },
- { LDAP_ATTR_LOGOFF_TIME, "logoffTime" },
- { LDAP_ATTR_KICKOFF_TIME, "kickoffTime" },
- { LDAP_ATTR_CN, "cn" },
- { LDAP_ATTR_DISPLAY_NAME, "displayName" },
- { LDAP_ATTR_HOME_PATH, "smbHome" },
- { LDAP_ATTR_HOME_DRIVE, "homeDrives" },
- { LDAP_ATTR_LOGON_SCRIPT, "scriptPath" },
- { LDAP_ATTR_PROFILE_PATH, "profilePath" },
- { LDAP_ATTR_DESC, "description" },
- { LDAP_ATTR_USER_WKS, "userWorkstations"},
- { LDAP_ATTR_USER_RID, "rid" },
- { LDAP_ATTR_PRIMARY_GROUP_RID, "primaryGroupID"},
- { LDAP_ATTR_LMPW, "lmPassword" },
- { LDAP_ATTR_NTPW, "ntPassword" },
- { LDAP_ATTR_DOMAIN, "domain" },
- { LDAP_ATTR_OBJCLASS, "objectClass" },
- { LDAP_ATTR_ACB_INFO, "acctFlags" },
- { LDAP_ATTR_LIST_END, NULL }
-};
-
-/* attributes used by Samba 3.0's sambaSamAccount */
-
-static ATTRIB_MAP_ENTRY attrib_map_v30[] = {
- { LDAP_ATTR_UID, "uid" },
- { LDAP_ATTR_UIDNUMBER, "uidNumber" },
- { LDAP_ATTR_GIDNUMBER, "gidNumber" },
- { LDAP_ATTR_UNIX_HOME, "homeDirectory" },
- { LDAP_ATTR_PWD_LAST_SET, "sambaPwdLastSet" },
- { LDAP_ATTR_PWD_CAN_CHANGE, "sambaPwdCanChange" },
- { LDAP_ATTR_PWD_MUST_CHANGE, "sambaPwdMustChange" },
- { LDAP_ATTR_LOGON_TIME, "sambaLogonTime" },
- { LDAP_ATTR_LOGOFF_TIME, "sambaLogoffTime" },
- { LDAP_ATTR_KICKOFF_TIME, "sambaKickoffTime" },
- { LDAP_ATTR_CN, "cn" },
- { LDAP_ATTR_DISPLAY_NAME, "displayName" },
- { LDAP_ATTR_HOME_DRIVE, "sambaHomeDrive" },
- { LDAP_ATTR_HOME_PATH, "sambaHomePath" },
- { LDAP_ATTR_LOGON_SCRIPT, "sambaLogonScript" },
- { LDAP_ATTR_PROFILE_PATH, "sambaProfilePath" },
- { LDAP_ATTR_DESC, "description" },
- { LDAP_ATTR_USER_WKS, "sambaUserWorkstations" },
- { LDAP_ATTR_USER_SID, "sambaSID" },
- { LDAP_ATTR_PRIMARY_GROUP_SID, "sambaPrimaryGroupSID" },
- { LDAP_ATTR_LMPW, "sambaLMPassword" },
- { LDAP_ATTR_NTPW, "sambaNTPassword" },
- { LDAP_ATTR_DOMAIN, "sambaDomainName" },
- { LDAP_ATTR_OBJCLASS, "objectClass" },
- { LDAP_ATTR_ACB_INFO, "sambaAcctFlags" },
- { LDAP_ATTR_LIST_END, NULL }
-};
-
-/* attributes used for alalocating RIDs */
-
-static ATTRIB_MAP_ENTRY dominfo_attr_list[] = {
- { LDAP_ATTR_DOMAIN, "sambaDomainName" },
- { LDAP_ATTR_NEXT_USERRID, "sambaNextUserRid" },
- { LDAP_ATTR_NEXT_GROUPRID, "sambaNextGroupRid" },
- { LDAP_ATTR_DOM_SID, "sambaSID" },
- { LDAP_ATTR_LIST_END, NULL },
-};
-
-/* Samba 3.0 group mapping attributes */
-
-static ATTRIB_MAP_ENTRY groupmap_attr_list[] = {
- { LDAP_ATTR_GIDNUMBER, "gidNumber" },
- { LDAP_ATTR_GROUP_SID, "sambaSID" },
- { LDAP_ATTR_GROUP_TYPE, "sambaGroupType" },
- { LDAP_ATTR_DESC, "description" },
- { LDAP_ATTR_DISPLAY_NAME, "displayName" },
- { LDAP_ATTR_CN, "cn" },
- { LDAP_ATTR_LIST_END, NULL }
-};
-
-static ATTRIB_MAP_ENTRY groupmap_attr_list_to_delete[] = {
- { LDAP_ATTR_GROUP_SID, "sambaSID" },
- { LDAP_ATTR_GROUP_TYPE, "sambaGroupType" },
- { LDAP_ATTR_DESC, "description" },
- { LDAP_ATTR_DISPLAY_NAME, "displayName" },
- { LDAP_ATTR_LIST_END, NULL }
-};
-
-/**********************************************************************
- perform a simple table lookup and return the attribute name
- **********************************************************************/
-
-static const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key )
-{
- int i = 0;
-
- while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
- if ( table[i].attrib == key )
- return table[i].name;
- i++;
- }
-
- return NULL;
-}
/**********************************************************************
get the attribute name given a user schame version
@@ -287,52 +118,6 @@ static const char* get_userattr_key2string( int schema_ver, int key )
}
/**********************************************************************
- Return the list of attribute names from a mapping table
- **********************************************************************/
-
-static char** get_attr_list( ATTRIB_MAP_ENTRY table[] )
-{
- char **names;
- int i = 0;
-
- while ( table[i].attrib != LDAP_ATTR_LIST_END )
- i++;
- i++;
-
- names = (char**)malloc( sizeof(char*)*i );
- if ( !names ) {
- DEBUG(0,("get_attr_list: out of memory\n"));
- return NULL;
- }
-
- i = 0;
- while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
- names[i] = strdup( table[i].name );
- i++;
- }
- names[i] = NULL;
-
- return names;
-}
-
-/*********************************************************************
- Cleanup
- ********************************************************************/
-
-static void free_attr_list( char **list )
-{
- int i = 0;
-
- if ( !list )
- return;
-
- while ( list[i] )
- SAFE_FREE( list[i] );
-
- SAFE_FREE( list );
-}
-
-/**********************************************************************
return the list of attribute names given a user schema version
**********************************************************************/
@@ -352,70 +137,6 @@ static char** get_userattr_list( int schema_ver )
return NULL;
}
-
-/*******************************************************************
- find the ldap password
-******************************************************************/
-static BOOL fetch_ldapsam_pw(char **dn, char** pw)
-{
- char *key = NULL;
- size_t size;
-
- *dn = smb_xstrdup(lp_ldap_admin_dn());
-
- if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
- SAFE_FREE(*dn);
- DEBUG(0, ("fetch_ldapsam_pw: asprintf failed!\n"));
- }
-
- *pw=secrets_fetch(key, &size);
- SAFE_FREE(key);
-
- if (!size) {
- /* Upgrade 2.2 style entry */
- char *p;
- char* old_style_key = strdup(*dn);
- char *data;
- fstring old_style_pw;
-
- if (!old_style_key) {
- DEBUG(0, ("fetch_ldapsam_pw: strdup failed!\n"));
- return False;
- }
-
- for (p=old_style_key; *p; p++)
- if (*p == ',') *p = '/';
-
- data=secrets_fetch(old_style_key, &size);
- if (!size && size < sizeof(old_style_pw)) {
- DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
- SAFE_FREE(old_style_key);
- SAFE_FREE(*dn);
- return False;
- }
-
- strncpy(old_style_pw, data, size);
- old_style_pw[size] = 0;
-
- SAFE_FREE(data);
-
- if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
- DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
- SAFE_FREE(old_style_key);
- SAFE_FREE(*dn);
- return False;
- }
- if (!secrets_delete(old_style_key)) {
- DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
- }
-
- SAFE_FREE(old_style_key);
-
- *pw = smb_xstrdup(old_style_pw);
- }
-
- return True;
-}
/*******************************************************************
open a connection to the ldap server.
@@ -632,7 +353,7 @@ static int ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ld
static_ldap_state = ldap_state;
/* get the password */
- if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
+ if (!fetch_ldap_pw(&ldap_dn, &ldap_secret))
{
DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
return LDAP_INVALID_CREDENTIALS;
diff --git a/source3/sam/idmap_ldap.c b/source3/sam/idmap_ldap.c
index 22d9fd0666..352b998cef 100644
--- a/source3/sam/idmap_ldap.c
+++ b/source3/sam/idmap_ldap.c
@@ -3,9 +3,10 @@
idmap LDAP backend
- Copyright (C) Tim Potter 2000
- Copyright (C) Anthony Liguori 2003
- Copyright (C) Simo Sorce 2003
+ Copyright (C) Tim Potter 2000
+ Copyright (C) Anthony Liguori 2003
+ Copyright (C) Simo Sorce 2003
+ Copyright (C) Gerald Carter 2003
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
@@ -31,6 +32,9 @@
#include <lber.h>
#include <ldap.h>
+#include "smbldap.h"
+
+
struct ldap_idmap_state {
LDAP *ldap_struct;
time_t last_ping;
@@ -53,70 +57,6 @@ static NTSTATUS ldap_idmap_close(void);
/*******************************************************************
- find the ldap password
-******************************************************************/
-static BOOL fetch_ldapsam_pw(char **dn, char** pw)
-{
- char *key = NULL;
- size_t size;
-
- *dn = smb_xstrdup(lp_ldap_admin_dn());
-
- if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
- SAFE_FREE(*dn);
- DEBUG(0, ("fetch_ldapsam_pw: asprintf failed!\n"));
- }
-
- *pw=secrets_fetch(key, &size);
- SAFE_FREE(key);
-
- if (!size) {
- /* Upgrade 2.2 style entry */
- char *p;
- char* old_style_key = strdup(*dn);
- char *data;
- fstring old_style_pw;
-
- if (!old_style_key) {
- DEBUG(0, ("fetch_ldapsam_pw: strdup failed!\n"));
- return False;
- }
-
- for (p=old_style_key; *p; p++)
- if (*p == ',') *p = '/';
-
- data=secrets_fetch(old_style_key, &size);
- if (!size && size < sizeof(old_style_pw)) {
- DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
- SAFE_FREE(old_style_key);
- SAFE_FREE(*dn);
- return False;
- }
-
- strncpy(old_style_pw, data, size);
- old_style_pw[size] = 0;
-
- SAFE_FREE(data);
-
- if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
- DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
- SAFE_FREE(old_style_key);
- SAFE_FREE(*dn);
- return False;
- }
- if (!secrets_delete(old_style_key)) {
- DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
- }
-
- SAFE_FREE(old_style_key);
-
- *pw = smb_xstrdup(old_style_pw);
- }
-
- return True;
-}
-
-/*******************************************************************
open a connection to the ldap server.
******************************************************************/
static int ldap_idmap_open_connection(struct ldap_idmap_state *state)
@@ -284,6 +224,9 @@ static int ldap_idmap_open(struct ldap_idmap_state *state)
return LDAP_SUCCESS;
}
+/*******************************************************************
+******************************************************************/
+
static int ldap_idmap_retry_open(struct ldap_idmap_state *state, int *attempts)
{
int rc;
@@ -319,6 +262,7 @@ static int ldap_idmap_retry_open(struct ldap_idmap_state *state, int *attempts)
a rebind function for authenticated referrals
This version takes a void* that we can shove useful stuff in :-)
******************************************************************/
+
#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
#else
static int rebindproc_with_state (LDAP * ld, char **whop, char **credp,
@@ -421,7 +365,7 @@ static int ldap_idmap_connect_system(struct ldap_idmap_state *state)
char *ldap_secret;
/* get the password */
- if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
+ if (!fetch_ldap_pw(&ldap_dn, &ldap_secret))
{
DEBUG(0, ("ldap_idmap_connect_system: Failed to retrieve "
"password from secrets.tdb\n"));
@@ -478,9 +422,13 @@ static int ldap_idmap_connect_system(struct ldap_idmap_state *state)
return rc;
}
+/*****************************************************************************
+ wrapper around ldap_search()
+*****************************************************************************/
+
static int ldap_idmap_search(struct ldap_idmap_state *state,
const char *base, int scope, const char *filter,
- const char *attrs[], int attrsonly,
+ char *attrs[], int attrsonly,
LDAPMessage **res)
{
int rc = LDAP_SERVER_DOWN;
@@ -510,9 +458,10 @@ static int ldap_idmap_search(struct ldap_idmap_state *state,
return rc;
}
-/*******************************************************************
-search an attribute and return the first value found.
-******************************************************************/
+/***********************************************************************
+ search an attribute and return the first value found.
+***********************************************************************/
+
static BOOL ldap_idmap_attribute (struct ldap_idmap_state *state,
LDAPMessage * entry,
const char *attribute, pstring value)
@@ -520,12 +469,16 @@ static BOOL ldap_idmap_attribute (struct ldap_idmap_state *state,
char **values;
value[0] = '\0';
- if ((values = ldap_get_values (state->ldap_struct, entry, attribute))
- == NULL) {
+ if ( !entry )
+ return False;
+
+ if ((values = ldap_get_values (state->ldap_struct, entry, attribute)) == NULL)
+ {
DEBUG(10,("get_single_attribute: [%s] = [<does not exist>]\n",
attribute));
return False;
}
+
if (convert_string(CH_UTF8, CH_UNIX,
values[0], -1,
value, sizeof(pstring)) == (size_t)-1)
@@ -540,9 +493,9 @@ static BOOL ldap_idmap_attribute (struct ldap_idmap_state *state,
return True;
}
-static const char *attrs[] = {"objectClass", "uidNumber", "gidNumber",
- "ntSid", NULL};
-static const char *pool_attr[] = {"uidNumber", "gidNumber", NULL};
+/*****************************************************************************
+ Allocate a new uid or gid
+*****************************************************************************/
static NTSTATUS ldap_allocate_id(unid_t *id, int id_type)
{
@@ -554,21 +507,34 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type)
pstring id_str, new_id_str;
LDAPMod mod[2];
LDAPMod *mods[3];
- const char *type = (id_type & ID_USERID) ? "uidNumber" : "gidNumber";
+ const char *type;
char *val[4];
char *dn;
+ char **attr_list;
+ pstring filter;
+
+ type = (id_type & ID_USERID) ?
+ get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ) :
+ get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER );
+
+ snprintf(filter, sizeof(filter)-1, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
+
+ attr_list = get_attr_list( idpool_attr_list );
+
rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, "(objectClass=unixIdPool)",
- pool_attr, 0, &result);
+ LDAP_SCOPE_SUBTREE, filter,
+ attr_list, 0, &result);
+ free_attr_list( attr_list );
+
if (rc != LDAP_SUCCESS) {
- DEBUG(0,("ldap_allocate_id: unixIdPool object not found\n"));
+ DEBUG(0,("ldap_allocate_id: %s object not found\n", LDAP_OBJ_IDPOOL));
goto out;
}
count = ldap_count_entries(ldap_state.ldap_struct, result);
if (count != 1) {
- DEBUG(0,("ldap_allocate_id: single unixIdPool not found\n"));
+ DEBUG(0,("ldap_allocate_id: single %s object not found\n", LDAP_OBJ_IDPOOL));
goto out;
}
@@ -580,210 +546,303 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type)
type));
goto out;
}
- if (id_type & ID_USERID) {
+
+ if (id_type & ID_USERID)
id->uid = strtoul(id_str, NULL, 10);
- } else {
+ else
id->gid = strtoul(id_str, NULL, 10);
- }
+
mod[0].mod_op = LDAP_MOD_DELETE;
mod[0].mod_type = strdup(type);
- val[0] = id_str; val[1] = NULL;
+ val[0] = id_str;
+ val[1] = NULL;
mod[0].mod_values = val;
- pstr_sprintf(new_id_str, "%ud",
+ snprintf(new_id_str, sizeof(new_id_str), "%u",
((id_type & ID_USERID) ? id->uid : id->gid) + 1);
mod[1].mod_op = LDAP_MOD_ADD;
mod[1].mod_type = strdup(type);
- val[3] = new_id_str; val[4] = NULL;
+ val[2] = new_id_str;
+ val[3] = NULL;
mod[1].mod_values = val + 2;
- mods[0] = mod; mods[1] = mod + 1; mods[2] = NULL;
+ mods[0] = mod; \
+ mods[1] = mod + 1;
+ mods[2] = NULL;
+
rc = ldap_modify_s(ldap_state.ldap_struct, dn, mods);
+
ldap_memfree(dn);
+
+ SAFE_FREE( mod[0].mod_type );
+ SAFE_FREE( mod[1].mod_type );
- if (rc == LDAP_SUCCESS) ret = NT_STATUS_OK;
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(0,("ldap_allocate_id: Failed to allocate new %s. ldap_modify() failed.\n",
+ type));
+ goto out;
+ }
+
+ ret = NT_STATUS_OK;
out:
return ret;
}
-/* Get a sid from an id */
+/*****************************************************************************
+ get a sid from an id
+*****************************************************************************/
+
static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
{
LDAPMessage *result = 0;
LDAPMessage *entry = 0;
pstring sid_str;
pstring filter;
- char type = (id_type & ID_USERID) ? 'u' : 'g';
+ const char *type;
int rc;
int count;
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- pstr_sprintf(filter, "(&(%cidNumber=%ud)(objectClass=sambaAccount))",
- type, ((id_type & ID_USERID) ? id.uid : id.gid));
- rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, filter, attrs, 0,
- &result);
- if (rc != LDAP_SUCCESS) {
- goto out;
- }
+ char **attr_list;
+
+ type = (id_type & ID_USERID) ?
+ get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ) :
+ get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER );
+
+ /* first we try for a samba user or group mapping */
+
+ if ( id_type & ID_USERID ) {
+ snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%u))",
+ LDAP_OBJ_SAMBASAMACCOUNT, type, id.uid );
+ }
+ else {
+ snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%u))",
+ LDAP_OBJ_GROUPMAP, type, id.gid );
+ }
+
+ attr_list = get_attr_list( sidmap_attr_list );
+ rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(), LDAP_SCOPE_SUBTREE,
+ filter, attr_list, 0, &result);
+ if (rc != LDAP_SUCCESS)
+ goto out;
+
count = ldap_count_entries(ldap_state.ldap_struct, result);
+
+ /* fall back to looking up an idmap entry if we didn't find and
+ actual user or group */
+
if (count == 0) {
- pstr_sprintf(filter,
- "(&(objectClass=idmapEntry)(%cidNumber=%ud))",
- type, ((id_type & ID_USERID) ? id.uid : id.gid));
- rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, filter,
- attrs, 0, &result);
- if (rc != LDAP_SUCCESS) {
+ snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%u))",
+ LDAP_OBJ_IDMAP_ENTRY, type, ((id_type & ID_USERID) ? id.uid : id.gid));
+
+ rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(),
+ LDAP_SCOPE_SUBTREE, filter, attr_list, 0, &result);
+ if (rc != LDAP_SUCCESS)
goto out;
- }
- count = ldap_count_entries(ldap_state.ldap_struct, result);
+
+ count = ldap_count_entries(ldap_state.ldap_struct, result);
}
if (count != 1) {
- DEBUG(0,("ldap_get_sid_from_id: mapping not found for "
- "%cid: %ud\n", (id_type&ID_USERID)?'u':'g',
- ((id_type & ID_USERID) ? id.uid : id.gid)));
+ DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %u\n",
+ type, ((id_type & ID_USERID) ? id.uid : id.gid)));
goto out;
}
entry = ldap_first_entry(ldap_state.ldap_struct, result);
- if (!ldap_idmap_attribute(&ldap_state, entry, "ntSid", sid_str)) {
+ if ( !ldap_idmap_attribute(&ldap_state, entry, LDAP_ATTRIBUTE_SID, sid_str) )
goto out;
- }
- if (!string_to_sid(sid, sid_str)) {
+ if (!string_to_sid(sid, sid_str))
goto out;
- }
ret = NT_STATUS_OK;
out:
+ free_attr_list( attr_list );
+
return ret;
}
-/* Get an id from a sid */
-static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type,
- const DOM_SID *sid)
+/***********************************************************************
+ Get an id from a sid
+***********************************************************************/
+
+static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid)
{
LDAPMessage *result = 0;
LDAPMessage *entry = 0;
pstring sid_str;
pstring filter;
pstring id_str;
- const char *type = (*id_type & ID_USERID) ? "uidNumber" : "gidNumber";
- const char *class =
- (*id_type & ID_USERID) ? "sambaAccount" : "sambaGroupMapping";
+ const char *type;
+ const char *obj_class;
int rc;
int count;
+ char **attr_list;
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
+ /* first try getting the mapping from a samba user or group */
+
+ if ( *id_type & ID_USERID ) {
+ type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER );
+ obj_class = LDAP_OBJ_SAMBASAMACCOUNT;
+ }
+ else {
+ type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER );
+ obj_class = LDAP_OBJ_GROUPMAP;
+ }
sid_to_string(sid_str, sid);
- pstr_sprintf(filter, "(&(objectClass=%s)(ntSid=%s)", class, sid_str);
- rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
- if (rc != LDAP_SUCCESS) {
+ snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%s))", obj_class,
+ LDAP_ATTRIBUTE_SID, sid_str);
+
+ attr_list = get_attr_list( sidmap_attr_list );
+ rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(), LDAP_SCOPE_SUBTREE,
+ filter, attr_list, 0, &result);
+
+ if (rc != LDAP_SUCCESS)
goto out;
- }
+
count = ldap_count_entries(ldap_state.ldap_struct, result);
+
+ /* fall back to looking up an idmap entry if we didn't find and
+ actual user or group */
+
if (count == 0) {
- pstr_sprintf(filter,
- "(&(objectClass=idmapEntry)(ntSid=%s))", sid_str);
+ snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%s))",
+ LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_str);
- rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, filter,
- attrs, 0, &result);
- if (rc != LDAP_SUCCESS) {
- goto out;
- }
- count = ldap_count_entries(ldap_state.ldap_struct, result);
+ rc = ldap_idmap_search(&ldap_state, lp_ldap_suffix(),
+ LDAP_SCOPE_SUBTREE, filter, attr_list, 0, &result);
+
+ if (rc != LDAP_SUCCESS)
+ goto out;
+
+ count = ldap_count_entries(ldap_state.ldap_struct, result);
}
-
- /* our search filters may 2 objects in the case that a user and group
- rid are the same */
- if (count != 1 && count != 2) {
- DEBUG(0,
- ("ldap_get_id_from_sid: incorrect number of objects\n"));
+
+ if ( count > 1 ) {
+ DEBUG(0, ("ldap_get_id_from_sid: search %s returned more than on entry!\n",
+ filter));
goto out;
}
- entry = ldap_first_entry(ldap_state.ldap_struct, result);
- if (!ldap_idmap_attribute(&ldap_state, entry, type, id_str)) {
- entry = ldap_next_entry(ldap_state.ldap_struct, entry);
-
- if (!ldap_idmap_attribute(&ldap_state, entry, type, id_str)) {
- int i;
+ /* we might have an existing entry to work with so pull out the requested information */
+
+ if ( count )
+ entry = ldap_first_entry(ldap_state.ldap_struct, result);
+
+ /* if entry == NULL, then we will default to allocating a new id */
+
+ if ( !ldap_idmap_attribute(&ldap_state, entry, type, id_str) )
+ {
+ int i;
- for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) {
- ret = ldap_allocate_id(id, *id_type);
- if (NT_STATUS_IS_OK(ret)) {
- break;
- }
- }
- if (NT_STATUS_IS_OK(ret)) {
- ret = ldap_set_mapping(sid, *id, *id_type);
- } else {
- DEBUG(0,("ldap_allocate_id: cannot acquire id"
- " lock\n"));
- }
- } else {
- if ((*id_type & ID_USERID)) {
- id->uid = strtoul(id_str, NULL, 10);
- } else {
- id->gid = strtoul(id_str, NULL, 10);
- }
- ret = NT_STATUS_OK;
+ for (i = 0; i < LDAP_MAX_ALLOC_ID; i++)
+ {
+ ret = ldap_allocate_id(id, *id_type);
+ if ( NT_STATUS_IS_OK(ret) )
+ break;
}
- } else {
- if ((*id_type & ID_USERID)) {
+
+ if ( !NT_STATUS_IS_OK(ret) ) {
+ DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n"));
+ goto out;
+ }
+
+ ret = ldap_set_mapping(sid, *id, *id_type);
+
+ }
+ else
+ {
+ if ( (*id_type & ID_USERID) )
id->uid = strtoul(id_str, NULL, 10);
- } else {
+ else
id->gid = strtoul(id_str, NULL, 10);
- }
+
ret = NT_STATUS_OK;
}
out:
+ free_attr_list( attr_list );
+
return ret;
}
-/* This function cannot be called to modify a mapping, only set a new one */
+/***********************************************************************
+ This function cannot be called to modify a mapping, only set a new one
+***********************************************************************/
+
static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
{
pstring dn, sid_str, id_str;
- const char *type = (id_type & ID_USERID) ? "uidNumber" : "gidNumber";
- LDAPMod *mods[3];
- LDAPMod mod[2];
- char *val[4];
+ fstring type, obj_str, obj_str_val, attr_sid;
+ LDAPMod *mods[4];
+ LDAPMod mod[3];
+ char *val[6];
int rc;
int attempts = 0;
- pstr_sprintf(id_str, "%ud", ((id_type & ID_USERID) ? id.uid : id.gid));
- sid_to_string(sid_str, sid);
- pstr_sprintf(dn, "%s=%ud,%s", type, ((id_type & ID_USERID) ? id.uid : id.gid), lp_ldap_suffix());
- mod[0].mod_op = LDAP_MOD_REPLACE;
- mod[0].mod_type = strdup(type);
- val[0] = id_str; val[1] = NULL;
+ if ( id_type & ID_USERID )
+ fstrcpy( type, get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ) );
+ else
+ fstrcpy( type, get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER ) );
+
+ snprintf(dn, sizeof(dn), "%s=%u,%s", type, ((id_type & ID_USERID) ? id.uid : id.gid),
+ lp_ldap_suffix());
+
+ fstrcpy( obj_str, "objectClass" );
+ fstrcpy( obj_str_val, LDAP_OBJ_IDMAP_ENTRY );
+ fstrcpy( attr_sid, LDAP_ATTRIBUTE_SID );
+
+ /* objectClass */
+
+ mod[0].mod_op = LDAP_MOD_ADD;
+ mod[0].mod_type = obj_str;
+ val[0] = obj_str_val;
+ val[1] = NULL;
mod[0].mod_values = val;
- mod[1].mod_op = LDAP_MOD_REPLACE;
- mod[1].mod_type = strdup("ntSid");
- val[2] = sid_str; val[3] = NULL;
- mod[1].mod_values = val + 2;
+ /* uid or gid */
+
+ snprintf(id_str, sizeof(id_str), "%u", ((id_type & ID_USERID) ? id.uid : id.gid));
+ mod[1].mod_op = LDAP_MOD_ADD;
+ mod[1].mod_type = type;
+ val[2] = id_str;
+ val[3] = NULL;
+ mod[1].mod_values = val+2;
- mods[0] = mod; mods[1] = mod + 1; mods[2] = NULL;
+ /* SID */
+
+ sid_to_string(sid_str, sid);
+ mod[2].mod_op = LDAP_MOD_ADD;
+ mod[2].mod_type = attr_sid;
+ val[4] = sid_str;
+ val[5] = NULL;
+ mod[2].mod_values = val+4;
+
+ mods[0] = mod;
+ mods[1] = mod + 1;
+ mods[2] = mod + 2;
+ mods[3] = NULL;
do {
- if ((rc = ldap_idmap_retry_open(&ldap_state, &attempts)) !=
- LDAP_SUCCESS) continue;
+ if ((rc = ldap_idmap_retry_open(&ldap_state, &attempts)) != LDAP_SUCCESS)
+ continue;
- rc = ldap_modify_s(ldap_state.ldap_struct, dn, mods);
+ rc = ldap_add_s(ldap_state.ldap_struct, dn, mods);
} while ((rc == LDAP_SERVER_DOWN) && (attempts <= 8));
+
if (rc != LDAP_SUCCESS) {
+ DEBUG(0,("ldap_set_mapping: Failed to create mapping from %s to %d [%s]\n",
+ sid_str, ((id_type & ID_USERID) ? id.uid : id.gid), type));
return NT_STATUS_UNSUCCESSFUL;
}
+
+ DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to %d [%s]\n",
+ sid_str, ((id_type & ID_USERID) ? id.uid : id.gid), type));
return NT_STATUS_OK;
}
@@ -799,7 +858,10 @@ static NTSTATUS ldap_idmap_init(void)
return NT_STATUS_OK;
}
-/* End the LDAP session */
+/*****************************************************************************
+ End the LDAP session
+*****************************************************************************/
+
static NTSTATUS ldap_idmap_close(void)
{
if (ldap_state.ldap_struct != NULL) {