mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb is ever different to LDAP, it is overwritten out of LDAP. We also store the 'algorithmic rid base' into LDAP, and assert if it changes. (This ensures cross-host synchronisation, and allows for possible integration with idmap). If we fail to read/add the domain entry, we just fallback to the old behaviour. We always use an existing DN when adding IDMAP entries to LDAP, unless no suitable entry is available. This means that a user's posixAccount will have a SID added to it, or a user's sambaSamAccount will have a UID added. Where we cannot us an existing DN, we use 'sambaSid=S-x-y-z,....' as the DN. The code now allows modifications to the ID mapping in many cases. Likewise, we now check more carefully when adding new user entires to LDAP, to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount onto the idmap entry for that user, if it is already established (ensuring we do not duplicate sambaSid entries in the directory). The allocated UID code has been expanded to take into account the space between '1000 - algorithmic rid base'. This much better fits into what an NT4 does - allocating in the bottom part of the RID range. On the code cleanup side of things, we now share as much code as possible between idmap_ldap and pdb_ldap. We also no longer use the race-prone 'enumerate all users' method for finding the next RID to allocate. Instead, we just start at the bottom of the range, and increment again if the user already exists. The first time this is run, it may well take a long time, but next time will just be able to use the next Rid. Thanks to metze and AB for double-checking parts of this. Andrew Bartlett
This commit is contained in:
parent
5280c69531
commit
9c595c8c23
@ -276,6 +276,16 @@ attributetype ( 1.3.6.1.4.1.7165.2.1.22 NAME 'sambaNextGroupRid'
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7165.2.1.39 NAME 'sambaNextRid'
|
||||
DESC 'Next NT rid to give out for anything'
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBase'
|
||||
DESC 'Base at which the samba RID generation algorithm should operate'
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
|
||||
#######################################################################
|
||||
## objectClasses used by Samba 3.0 schema ##
|
||||
@ -312,16 +322,23 @@ objectclass ( 1.3.6.1.4.1.7165.2.2.4 NAME 'sambaGroupMapping' SUP top AUXILIARY
|
||||
##
|
||||
objectclass ( 1.3.6.1.4.1.7165.2.2.5 NAME 'sambaDomain' SUP top STRUCTURAL
|
||||
DESC 'Samba Domain Information'
|
||||
MUST ( sambaDomainName $ sambaNextGroupRid $ sambaNextUserRid $
|
||||
sambaSID ) )
|
||||
MUST ( sambaDomainName $
|
||||
sambaSID )
|
||||
MAY ( sambaNextRid $ sambaNextGroupRid $ sambaNextUserRid $
|
||||
sambaAlgorithmicRidBase ) )
|
||||
|
||||
## 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
|
||||
|
||||
objectclass ( 1.3.6.1.4.1.7165.1.2.2.8 NAME 'sambaIdmapEntry' SUP top AUXILIARY
|
||||
DESC 'Mapping from a SID to an ID'
|
||||
MUST ( sambaSID )
|
||||
MAY ( uidNumber $ gidNumber ))
|
||||
MAY ( uidNumber $ gidNumber ) )
|
||||
|
||||
objectclass ( 1.3.6.1.4.1.7165.1.2.2.9 NAME 'sambaSidEntry' SUP top STRUCTURAL
|
||||
DESC 'Structural Class for a SID'
|
||||
MUST ( sambaSID ) )
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#define LDAP_OBJ_DOMINFO "sambaDomain"
|
||||
#define LDAP_OBJ_IDPOOL "sambaUnixIdPool"
|
||||
#define LDAP_OBJ_IDMAP_ENTRY "sambaIdmapEntry"
|
||||
#define LDAP_OBJ_SID_ENTRY "sambaSidEntry"
|
||||
|
||||
#define LDAP_OBJ_ACCOUNT "account"
|
||||
#define LDAP_OBJ_POSIXACCOUNT "posixAccount"
|
||||
@ -85,7 +86,8 @@
|
||||
#define LDAP_ATTR_GROUP_SID 30
|
||||
#define LDAP_ATTR_GROUP_TYPE 31
|
||||
#define LDAP_ATTR_SID 32
|
||||
|
||||
#define LDAP_ATTR_ALGORITHMIC_RID_BASE 33
|
||||
#define LDAP_ATTR_NEXT_RID 34
|
||||
|
||||
typedef struct _attrib_map_entry {
|
||||
int attrib;
|
||||
@ -113,6 +115,8 @@ void smbldap_set_mod (LDAPMod *** modlist, int modop, const char *attribute, con
|
||||
void smbldap_make_mod(LDAP *ldap_struct, LDAPMessage *existing,
|
||||
LDAPMod ***mods,
|
||||
const char *attribute, const char *newval);
|
||||
BOOL smbldap_get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
|
||||
const char *attribute, pstring value);
|
||||
|
||||
/**
|
||||
* Struct to keep the state for all the ldap stuff
|
||||
|
@ -102,9 +102,11 @@ ATTRIB_MAP_ENTRY attrib_map_v30[] = {
|
||||
|
||||
ATTRIB_MAP_ENTRY dominfo_attr_list[] = {
|
||||
{ LDAP_ATTR_DOMAIN, "sambaDomainName" },
|
||||
{ LDAP_ATTR_NEXT_RID, "sambaNextRid" },
|
||||
{ LDAP_ATTR_NEXT_USERRID, "sambaNextUserRid" },
|
||||
{ LDAP_ATTR_NEXT_GROUPRID, "sambaNextGroupRid" },
|
||||
{ LDAP_ATTR_DOM_SID, LDAP_ATTRIBUTE_SID },
|
||||
{ LDAP_ATTR_ALGORITHMIC_RID_BASE,"sambaAlgorithmicRidBase"},
|
||||
{ LDAP_ATTR_LIST_END, NULL },
|
||||
};
|
||||
|
||||
@ -271,6 +273,40 @@ BOOL fetch_ldap_pw(char **dn, char** pw)
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
search an attribute and return the first value found.
|
||||
******************************************************************/
|
||||
BOOL smbldap_get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
|
||||
const char *attribute, pstring value)
|
||||
{
|
||||
char **values;
|
||||
|
||||
if ( !attribute )
|
||||
return False;
|
||||
|
||||
value[0] = '\0';
|
||||
|
||||
if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) {
|
||||
DEBUG (10, ("smbldap_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)
|
||||
{
|
||||
DEBUG(1, ("smbldap_get_single_attribute: string conversion of [%s] = [%s] failed!\n",
|
||||
attribute, values[0]));
|
||||
ldap_value_free(values);
|
||||
return False;
|
||||
}
|
||||
|
||||
ldap_value_free(values);
|
||||
#ifdef DEBUG_PASSWORDS
|
||||
DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n", attribute, value));
|
||||
#endif
|
||||
return True;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
Routine to manage the LDAPMod structure array
|
||||
manage memory used by the array, by each struct, and values
|
||||
@ -819,7 +855,7 @@ static NTSTATUS smbldap_close(struct smbldap_state *ldap_state)
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static int smbldap_retry_open(struct smbldap_state *ldap_state, int *attempts)
|
||||
int smbldap_retry_open(struct smbldap_state *ldap_state, int *attempts)
|
||||
{
|
||||
int rc;
|
||||
|
||||
|
@ -581,7 +581,7 @@ BOOL pdb_gethexpwd(const char *p, unsigned char *pwd)
|
||||
return (True);
|
||||
}
|
||||
|
||||
static int algorithmic_rid_base(void)
|
||||
int algorithmic_rid_base(void)
|
||||
{
|
||||
static int rid_offset = 0;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -132,7 +132,6 @@ BOOL idmap_get_free_ugid_range(uint32 *low, uint32 *high)
|
||||
*THE CANONICAL* convert uid_t to SID function.
|
||||
check idmap if uid is in idmap range, otherwise falls back to
|
||||
the legacy algorithmic mapping.
|
||||
A special cache is used for uids that maps to Wellknown SIDs
|
||||
Returns SID pointer.
|
||||
*****************************************************************/
|
||||
|
||||
@ -204,7 +203,6 @@ NTSTATUS gid_to_sid(DOM_SID *sid, gid_t gid)
|
||||
*THE CANONICAL* convert SID to uid function.
|
||||
if it is a foreign sid or it is in idmap rid range check idmap,
|
||||
otherwise falls back to the legacy algorithmic mapping.
|
||||
A special cache is used for uids that maps to Wellknown SIDs
|
||||
Returns True if this name is a user sid and the conversion
|
||||
was done correctly, False if not.
|
||||
*****************************************************************/
|
||||
@ -351,6 +349,7 @@ BOOL idmap_init_wellknown_sids(void)
|
||||
int num_entries=0;
|
||||
DOM_SID sid;
|
||||
unid_t id;
|
||||
fstring sid_string;
|
||||
|
||||
if (!(guest_account && *guest_account)) {
|
||||
DEBUG(1, ("NULL guest account!?!?\n"));
|
||||
@ -368,6 +367,8 @@ BOOL idmap_init_wellknown_sids(void)
|
||||
sid_append_rid(&sid, DOMAIN_USER_RID_GUEST);
|
||||
|
||||
if (!NT_STATUS_IS_OK(wellknown_id_init(&sid, id, ID_USERID))) {
|
||||
DEBUG(0, ("Failed to setup UID mapping for GUEST (%s) to (%u)\n",
|
||||
sid_to_string(sid_string, &sid), (unsigned int)id.uid));
|
||||
passwd_free(&pass);
|
||||
return False;
|
||||
}
|
||||
@ -378,6 +379,8 @@ BOOL idmap_init_wellknown_sids(void)
|
||||
sid_copy(&sid, get_global_sam_sid());
|
||||
sid_append_rid(&sid, DOMAIN_GROUP_RID_GUESTS);
|
||||
if (!NT_STATUS_IS_OK(wellknown_id_init(&sid, id, ID_GROUPID))) {
|
||||
DEBUG(0, ("Failed to setup GID mapping for Group DOMAIN GUESTS (%s) to (%u)\n",
|
||||
sid_to_string(sid_string, &sid), (unsigned int)id.gid));
|
||||
passwd_free(&pass);
|
||||
return False;
|
||||
}
|
||||
|
@ -842,9 +842,19 @@ void build_options(BOOL screen);
|
||||
if (!init_registry())
|
||||
exit(1);
|
||||
|
||||
/* Initialise the password backed before idmap and the global_sam_sid
|
||||
to ensure that we fetch from ldap before we make a domain sid up */
|
||||
|
||||
if(!initialize_password_db(False))
|
||||
exit(1);
|
||||
|
||||
if(!get_global_sam_sid()) {
|
||||
DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static_init_auth;
|
||||
|
||||
{
|
||||
const char *idmap_back = lp_idmap_backend();
|
||||
|
||||
@ -852,8 +862,10 @@ void build_options(BOOL screen);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!idmap_init_wellknown_sids())
|
||||
if (!idmap_init_wellknown_sids()) {
|
||||
DEBUG(0,("ERROR: Samba failed to initialize it's 'well known' SID -> ID mapping tables.\n"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static_init_rpc;
|
||||
|
||||
@ -862,12 +874,6 @@ void build_options(BOOL screen);
|
||||
/* possibly reload the services file. */
|
||||
reload_services(True);
|
||||
|
||||
if(!get_global_sam_sid()) {
|
||||
DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if (!init_account_policy()) {
|
||||
DEBUG(0,("Could not open account policy tdb.\n"));
|
||||
exit(1);
|
||||
|
@ -606,6 +606,12 @@ int main (int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Initialise the password backed before idmap and the global_sam_sid
|
||||
to ensure that we fetch from ldap before we make a domain sid up */
|
||||
|
||||
if(!initialize_password_db(False))
|
||||
exit(1);
|
||||
|
||||
if (!init_names())
|
||||
exit(1);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user