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:
parent
e8d5d89277
commit
3bdfd57a2d
@ -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 ))
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
101
source3/include/smbldap.h
Normal 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
259
source3/lib/smbldap.c
Normal 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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user