1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-27 22:50:26 +03:00

working draft of the idmap_ldap code.

Includes sambaUnixIdPool objectclass

Still needs cleaning up wrt to name space.
More changes to come, but at least we now have a
a working distributed winbindd solution.
(This used to be commit 824175854421f7c27d31ad673a8790dd018ae350)
This commit is contained in:
Gerald Carter 2003-06-05 02:34:30 +00:00
parent e8d5d89277
commit 3bdfd57a2d
8 changed files with 647 additions and 484 deletions

View File

@ -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 ))

View File

@ -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)

View File

@ -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

View File

@ -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"

101
source3/include/smbldap.h Normal file
View File

@ -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 */

259
source3/lib/smbldap.c Normal file
View File

@ -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;
}

View File

@ -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
@ -286,52 +117,6 @@ static const char* get_userattr_key2string( int schema_ver, int key )
return NULL;
}
/**********************************************************************
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;

View File

@ -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;
@ -52,70 +56,6 @@ static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type);
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.
******************************************************************/
@ -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);
if (rc == LDAP_SUCCESS) ret = NT_STATUS_OK;
ldap_memfree(dn);
SAFE_FREE( mod[0].mod_type );
SAFE_FREE( mod[1].mod_type );
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);
/* 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;
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) {