From: Matthew Chapman Date: Fri, 15 Jan 1999 05:00:26 +0000 (+0000) Subject: Finally committing my LDAP changes. X-Git-Tag: samba-4.0.0alpha6~801^2~20963 X-Git-Url: http://git.samba.org/?p=samba.git;a=commitdiff_plain;h=c35bf4578561af4f2971492f6ef826f10ac13860 Finally committing my LDAP changes. * Added new APIs for modifying groups. * RIDs are allocated similarly to NT, starting from 1000 and incrementing by 1 for each new user/group. * RIDs are now consistently in hex * Fixed bugs reported by Allan Bjorklund : - ldap_close_connection is exported by OpenLDAP - changed to ldap_disconnect - Missing ldap_connect() in getusergroups functions - ldap_next_entry was being called too early while retrieving a sam_struct - LDAP globals should be extern in sampassldap.c * Fixed bugs reported by Martin Hofbauer - Newly added workstation trust accounts had attributes DU rather than W. - User dn's were forced to start with "uid=XX" rather than using the existing dn. (This used to be commit 91c77f5432169553572bb4d85ad5f09d17524f20) --- diff --git a/source3/groupdb/aliasldap.c b/source3/groupdb/aliasldap.c index 35d810dabc2..1e9a72a9d41 100644 --- a/source3/groupdb/aliasldap.c +++ b/source3/groupdb/aliasldap.c @@ -61,7 +61,7 @@ static LOCAL_GRP *ldapalias_getgrp(LOCAL_GRP *group, DEBUG(2,("Retrieving alias [%s]\n", group->name)); if(ldap_get_attribute("rid", temp)) { - group->rid = atoi(temp); + group->rid = strtol(temp, NULL, 16); } else { DEBUG(0, ("Missing rid\n")); return NULL; @@ -128,10 +128,7 @@ static void ldapalias_grpmods(LOCAL_GRP *group, LDAPMod ***mods, int operation) ldap_make_mod(mods, LDAP_MOD_ADD, "objectClass", "sambaAlias"); ldap_make_mod(mods, LDAP_MOD_ADD, "cn", group->name); - slprintf(temp, sizeof(temp)-1, "%d", (gid_t)(-1)); - ldap_make_mod(mods, LDAP_MOD_ADD, "gidNumber", temp); - - slprintf(temp, sizeof(temp)-1, "%d", group->rid); + slprintf(temp, sizeof(temp)-1, "%x", group->rid); ldap_make_mod(mods, LDAP_MOD_ADD, "rid", temp); } @@ -139,6 +136,30 @@ static void ldapalias_grpmods(LOCAL_GRP *group, LDAPMod ***mods, int operation) } +/************************************************************************ + Create a alias member entry + ************************************************************************/ + +static BOOL ldapalias_memmods(DOM_SID *user_sid, LDAPMod ***mods, + int operation) +{ + pstring member; + pstring sid_str; + fstring name; + uint8 type; + + if (lookup_sid(user_sid, name, &type)) + return (False); + sid_to_string(sid_str, user_sid); + + slprintf(member, sizeof(member)-1, "%s,%s,%d", name, sid_str, type); + + *mods = NULL; + ldap_make_mod(mods, operation, "member", member); + return True; +} + + /*************************************************************** Begin/end smbgrp enumeration. ****************************************************************/ @@ -148,7 +169,7 @@ static void *ldapalias_enumfirst(BOOL update) if (lp_server_role() == ROLE_DOMAIN_NONE) return NULL; - if (!ldap_open_connection(False)) + if (!ldap_connect()) return NULL; ldap_search_for("objectClass=sambaAlias"); @@ -158,7 +179,7 @@ static void *ldapalias_enumfirst(BOOL update) static void ldapalias_enumclose(void *vp) { - ldap_close_connection(); + ldap_disconnect(); } @@ -188,7 +209,7 @@ static LOCAL_GRP *ldapalias_getgrpbynam(const char *name, fstring filter; LOCAL_GRP *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return (False); slprintf(filter, sizeof(filter)-1, @@ -197,7 +218,7 @@ static LOCAL_GRP *ldapalias_getgrpbynam(const char *name, ret = ldapalias_getgrp(&localgrp, members, num_membs); - ldap_close_connection(); + ldap_disconnect(); return ret; } @@ -207,7 +228,7 @@ static LOCAL_GRP *ldapalias_getgrpbygid(gid_t grp_id, fstring filter; LOCAL_GRP *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return (False); slprintf(filter, sizeof(filter)-1, @@ -215,7 +236,7 @@ static LOCAL_GRP *ldapalias_getgrpbygid(gid_t grp_id, ldap_search_for(filter); ret = ldapalias_getgrp(&localgrp, members, num_membs); - ldap_close_connection(); + ldap_disconnect(); return ret; } @@ -225,15 +246,15 @@ static LOCAL_GRP *ldapalias_getgrpbyrid(uint32 grp_rid, fstring filter; LOCAL_GRP *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return (False); slprintf(filter, sizeof(filter)-1, - "(&(rid=%d)(objectClass=sambaAlias))", grp_rid); + "(&(rid=%x)(objectClass=sambaAlias))", grp_rid); ldap_search_for(filter); ret = ldapalias_getgrp(&localgrp, members, num_membs); - ldap_close_connection(); + ldap_disconnect(); return ret; } @@ -243,10 +264,21 @@ static LOCAL_GRP *ldapalias_getcurrentgrp(void *vp, return ldapalias_getgrp(&localgrp, members, num_membs); } + +/************************************************************************* + Add/modify/delete aliases. + *************************************************************************/ + static BOOL ldapalias_addgrp(LOCAL_GRP *group) { LDAPMod **mods; + if (!ldap_allocaterid(&group->rid)) + { + DEBUG(0,("RID generation failed\n")); + return (False); + } + ldapalias_grpmods(group, &mods, LDAP_MOD_ADD); return ldap_makemods("cn", group->name, mods, True); } @@ -259,6 +291,74 @@ static BOOL ldapalias_modgrp(LOCAL_GRP *group) return ldap_makemods("cn", group->name, mods, False); } +static BOOL ldapalias_delgrp(uint32 grp_rid) +{ + fstring filter; + char *dn; + int err; + + if (!ldap_connect()) + return (False); + + slprintf(filter, sizeof(filter)-1, + "(&(rid=%x)(objectClass=sambaAlias))", grp_rid); + ldap_search_for(filter); + + if (!ldap_entry || !(dn = ldap_get_dn(ldap_struct, ldap_entry))) + { + ldap_disconnect(); + return (False); + } + + err = ldap_delete_s(ldap_struct, dn); + free(dn); + ldap_disconnect(); + + if (err != LDAP_SUCCESS) + { + DEBUG(0, ("delete: %s\n", ldap_err2string(err))); + return (False); + } + + return True; +} + + +/************************************************************************* + Add users to/remove users from aliases. + *************************************************************************/ + +static BOOL ldapalias_addmem(uint32 grp_rid, DOM_SID *user_sid) +{ + LDAPMod **mods; + fstring rid_str; + + slprintf(rid_str, sizeof(rid_str)-1, "%x", grp_rid); + + if(!ldapalias_memmods(user_sid, &mods, LDAP_MOD_ADD)) + return (False); + + return ldap_makemods("rid", rid_str, mods, False); +} + +static BOOL ldapalias_delmem(uint32 grp_rid, DOM_SID *user_sid) +{ + LDAPMod **mods; + fstring rid_str; + + slprintf(rid_str, sizeof(rid_str)-1, "%x", grp_rid); + + if(!ldapalias_memmods(user_sid, &mods, LDAP_MOD_DELETE)) + return (False); + + return ldap_makemods("rid", rid_str, mods, False); +} + + +/************************************************************************* + Return aliases that a user is in. + *************************************************************************/ + static BOOL ldapalias_getusergroups(const char *name, LOCAL_GRP **groups, int *num_grps) { @@ -266,6 +366,9 @@ static BOOL ldapalias_getusergroups(const char *name, LOCAL_GRP **groups, fstring filter; int i; + if(!ldap_connect()) + return (False); + slprintf(filter, sizeof(pstring)-1, "(&(member=%s,*)(objectclass=sambaAlias))", name); ldap_search_for(filter); @@ -274,6 +377,7 @@ static BOOL ldapalias_getusergroups(const char *name, LOCAL_GRP **groups, if(!i) { *groups = NULL; + ldap_disconnect(); return (True); } @@ -282,6 +386,7 @@ static BOOL ldapalias_getusergroups(const char *name, LOCAL_GRP **groups, i--; } while(ldapalias_getgrp(&grouplist[i], NULL, NULL) && (i > 0)); + ldap_disconnect(); return (True); } @@ -300,6 +405,10 @@ static struct aliasdb_ops ldapalias_ops = ldapalias_addgrp, ldapalias_modgrp, + ldapalias_delgrp, + + ldapalias_addmem, + ldapalias_delmem, ldapalias_getusergroups }; diff --git a/source3/groupdb/builtinldap.c b/source3/groupdb/builtinldap.c index f2a530cbb95..baac82f1bab 100644 --- a/source3/groupdb/builtinldap.c +++ b/source3/groupdb/builtinldap.c @@ -58,10 +58,10 @@ static LOCAL_GRP *ldapbuiltin_getgrp(LOCAL_GRP *group, DEBUG(0, ("Missing cn\n")); return NULL; } - DEBUG(2,("Retrieving alias [%s]\n", group->name)); + DEBUG(2,("Retrieving builtin alias [%s]\n", group->name)); if(ldap_get_attribute("rid", temp)) { - group->rid = atoi(temp); + group->rid = strtol(temp, NULL, 16); } else { DEBUG(0, ("Missing rid\n")); return NULL; @@ -129,10 +129,7 @@ static void ldapbuiltin_grpmods(LOCAL_GRP *group, LDAPMod ***mods, ldap_make_mod(mods, LDAP_MOD_ADD, "objectClass", "sambaBuiltin"); ldap_make_mod(mods, LDAP_MOD_ADD, "cn", group->name); - slprintf(temp, sizeof(temp)-1, "%d", (gid_t)(-1)); - ldap_make_mod(mods, LDAP_MOD_ADD, "gidNumber", temp); - - slprintf(temp, sizeof(temp)-1, "%d", group->rid); + slprintf(temp, sizeof(temp)-1, "%x", group->rid); ldap_make_mod(mods, LDAP_MOD_ADD, "rid", temp); } @@ -140,6 +137,30 @@ static void ldapbuiltin_grpmods(LOCAL_GRP *group, LDAPMod ***mods, } +/************************************************************************ + Create a builtin alias member entry + ************************************************************************/ + +static BOOL ldapbuiltin_memmods(DOM_SID *user_sid, LDAPMod ***mods, + int operation) +{ + pstring member; + pstring sid_str; + fstring name; + uint8 type; + + if (lookup_sid(user_sid, name, &type)) + return (False); + sid_to_string(sid_str, user_sid); + + slprintf(member, sizeof(member)-1, "%s,%s,%d", name, sid_str, type); + + *mods = NULL; + ldap_make_mod(mods, operation, "member", member); + return True; +} + + /*************************************************************** Begin/end smbgrp enumeration. ****************************************************************/ @@ -149,7 +170,7 @@ static void *ldapbuiltin_enumfirst(BOOL update) if (lp_server_role() == ROLE_DOMAIN_NONE) return NULL; - if (!ldap_open_connection(False)) + if (!ldap_connect()) return NULL; ldap_search_for("objectClass=sambaBuiltin"); @@ -159,7 +180,7 @@ static void *ldapbuiltin_enumfirst(BOOL update) static void ldapbuiltin_enumclose(void *vp) { - ldap_close_connection(); + ldap_disconnect(); } @@ -189,7 +210,7 @@ static LOCAL_GRP *ldapbuiltin_getgrpbynam(const char *name, fstring filter; LOCAL_GRP *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return (False); slprintf(filter, sizeof(filter)-1, @@ -198,7 +219,7 @@ static LOCAL_GRP *ldapbuiltin_getgrpbynam(const char *name, ret = ldapbuiltin_getgrp(&localgrp, members, num_membs); - ldap_close_connection(); + ldap_disconnect(); return ret; } @@ -208,7 +229,7 @@ static LOCAL_GRP *ldapbuiltin_getgrpbygid(gid_t grp_id, fstring filter; LOCAL_GRP *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return (False); slprintf(filter, sizeof(filter)-1, @@ -216,7 +237,7 @@ static LOCAL_GRP *ldapbuiltin_getgrpbygid(gid_t grp_id, ldap_search_for(filter); ret = ldapbuiltin_getgrp(&localgrp, members, num_membs); - ldap_close_connection(); + ldap_disconnect(); return ret; } @@ -226,15 +247,15 @@ static LOCAL_GRP *ldapbuiltin_getgrpbyrid(uint32 grp_rid, fstring filter; LOCAL_GRP *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return (False); slprintf(filter, sizeof(filter)-1, - "(&(rid=%d)(objectClass=sambaBuiltin))", grp_rid); + "(&(rid=%x)(objectClass=sambaBuiltin))", grp_rid); ldap_search_for(filter); ret = ldapbuiltin_getgrp(&localgrp, members, num_membs); - ldap_close_connection(); + ldap_disconnect(); return ret; } @@ -244,10 +265,21 @@ static LOCAL_GRP *ldapbuiltin_getcurrentgrp(void *vp, return ldapbuiltin_getgrp(&localgrp, members, num_membs); } + +/************************************************************************* + Add/modify/delete builtin aliases. + *************************************************************************/ + static BOOL ldapbuiltin_addgrp(LOCAL_GRP *group) { LDAPMod **mods; + if (!ldap_allocaterid(&group->rid)) + { + DEBUG(0,("RID generation failed\n")); + return (False); + } + ldapbuiltin_grpmods(group, &mods, LDAP_MOD_ADD); return ldap_makemods("cn", group->name, mods, True); } @@ -260,6 +292,74 @@ static BOOL ldapbuiltin_modgrp(LOCAL_GRP *group) return ldap_makemods("cn", group->name, mods, False); } +static BOOL ldapbuiltin_delgrp(uint32 grp_rid) +{ + fstring filter; + char *dn; + int err; + + if (!ldap_connect()) + return (False); + + slprintf(filter, sizeof(filter)-1, + "(&(rid=%x)(objectClass=sambaBuiltin))", grp_rid); + ldap_search_for(filter); + + if (!ldap_entry || !(dn = ldap_get_dn(ldap_struct, ldap_entry))) + { + ldap_disconnect(); + return (False); + } + + err = ldap_delete_s(ldap_struct, dn); + free(dn); + ldap_disconnect(); + + if (err != LDAP_SUCCESS) + { + DEBUG(0, ("delete: %s\n", ldap_err2string(err))); + return (False); + } + + return True; +} + + +/************************************************************************* + Add users to/remove users from aliases. + *************************************************************************/ + +static BOOL ldapbuiltin_addmem(uint32 grp_rid, DOM_SID *user_sid) +{ + LDAPMod **mods; + fstring rid_str; + + slprintf(rid_str, sizeof(rid_str)-1, "%x", grp_rid); + + if(!ldapbuiltin_memmods(user_sid, &mods, LDAP_MOD_ADD)) + return (False); + + return ldap_makemods("rid", rid_str, mods, False); +} + +static BOOL ldapbuiltin_delmem(uint32 grp_rid, DOM_SID *user_sid) +{ + LDAPMod **mods; + fstring rid_str; + + slprintf(rid_str, sizeof(rid_str)-1, "%x", grp_rid); + + if(!ldapbuiltin_memmods(user_sid, &mods, LDAP_MOD_DELETE)) + return (False); + + return ldap_makemods("rid", rid_str, mods, False); +} + + +/************************************************************************* + Return builtin aliases that a user is in. + *************************************************************************/ + static BOOL ldapbuiltin_getusergroups(const char *name, LOCAL_GRP **groups, int *num_grps) { @@ -267,6 +367,9 @@ static BOOL ldapbuiltin_getusergroups(const char *name, fstring filter; int i; + if(!ldap_connect()) + return (False); + slprintf(filter, sizeof(pstring)-1, "(&(member=%s,*)(objectclass=sambaBuiltin))", name); ldap_search_for(filter); @@ -275,6 +378,7 @@ static BOOL ldapbuiltin_getusergroups(const char *name, if(!i) { *groups = NULL; + ldap_disconnect(); return (True); } @@ -283,6 +387,7 @@ static BOOL ldapbuiltin_getusergroups(const char *name, i--; } while(ldapbuiltin_getgrp(&grouplist[i], NULL, NULL) && (i > 0)); + ldap_disconnect(); return (True); } @@ -301,6 +406,10 @@ static struct aliasdb_ops ldapbuiltin_ops = ldapbuiltin_addgrp, ldapbuiltin_modgrp, + ldapbuiltin_delgrp, + + ldapbuiltin_addmem, + ldapbuiltin_delmem, ldapbuiltin_getusergroups }; diff --git a/source3/groupdb/groupldap.c b/source3/groupdb/groupldap.c index df0d7552402..4411ead14ca 100644 --- a/source3/groupdb/groupldap.c +++ b/source3/groupdb/groupldap.c @@ -28,6 +28,7 @@ #include extern int DEBUGLEVEL; +extern DOM_SID global_sam_sid; /* Internal state */ extern LDAP *ldap_struct; @@ -48,6 +49,7 @@ static DOMAIN_GRP *ldapgroup_getgrp(DOMAIN_GRP *group, fstring temp; char **values; DOMAIN_GRP_MEMBER *memblist; + char *value, *sep; int i; if(!ldap_entry) @@ -60,7 +62,7 @@ static DOMAIN_GRP *ldapgroup_getgrp(DOMAIN_GRP *group, DEBUG(2,("Retrieving group [%s]\n", group->name)); if(ldap_get_attribute("rid", temp)) { - group->rid = atoi(temp); + group->rid = strtol(temp, NULL, 16); } else { DEBUG(0, ("Missing rid\n")); return NULL; @@ -76,16 +78,33 @@ static DOMAIN_GRP *ldapgroup_getgrp(DOMAIN_GRP *group, return group; } - if(values = ldap_get_values(ldap_struct, ldap_entry, "uidMember")) { - - DEBUG(0, ("Need to return NT names here\n")); + if(values = ldap_get_values(ldap_struct, ldap_entry, "member")) { *num_membs = i = ldap_count_values(values); *members = memblist = malloc(i * sizeof(DOMAIN_GRP_MEMBER)); do { - fstrcpy(memblist[--i].name, values[i]); + value = values[--i]; + + if(!(sep = strchr(value, ','))) { + DEBUG(0, ("Malformed group member\n")); + return NULL; + } + *(sep++) = 0; + fstrcpy(memblist[i].name, value); + + if(!(value = strchr(sep, ','))) { + DEBUG(0, ("Malformed group member\n")); + return NULL; + } + memblist[i].rid = strtol(sep, &value, 16); + + if((memblist[i].sid_use = atoi(value+1)) + >= SID_NAME_UNKNOWN) + DEBUG(0, ("Invalid SID use in group")); + memblist[i].attr = 0x7; + } while(i > 0); ldap_value_free(values); @@ -115,10 +134,7 @@ static void ldapgroup_grpmods(DOMAIN_GRP *group, LDAPMod ***mods, ldap_make_mod(mods, LDAP_MOD_ADD, "objectClass", "sambaGroup"); ldap_make_mod(mods, LDAP_MOD_ADD, "cn", group->name); - slprintf(temp, sizeof(temp)-1, "%d", (gid_t)(-1)); - ldap_make_mod(mods, LDAP_MOD_ADD, "gidNumber", temp); - - slprintf(temp, sizeof(temp)-1, "%d", group->rid); + slprintf(temp, sizeof(temp)-1, "%x", group->rid); ldap_make_mod(mods, LDAP_MOD_ADD, "rid", temp); } @@ -126,6 +142,30 @@ static void ldapgroup_grpmods(DOMAIN_GRP *group, LDAPMod ***mods, } +/************************************************************************ + Create a group member entry + ************************************************************************/ + +static BOOL ldapgroup_memmods(uint32 user_rid, LDAPMod ***mods, int operation) +{ + pstring member; + fstring name; + DOM_SID sid; + uint8 type; + + sid_copy(&sid, &global_sam_sid); + sid_append_rid(&sid, user_rid); + if (lookup_sid(&sid, name, &type)) + return (False); + + slprintf(member, sizeof(member)-1, "%s,%x,%d", name, user_rid, type); + + *mods = NULL; + ldap_make_mod(mods, operation, "member", member); + return True; +} + + /*************************************************************** Begin/end domain group enumeration. ****************************************************************/ @@ -138,7 +178,7 @@ static void *ldapgroup_enumfirst(BOOL update) server_role == ROLE_DOMAIN_MEMBER) return NULL; - if (!ldap_open_connection(False)) + if (!ldap_connect()) return NULL; ldap_search_for("objectclass=sambaGroup"); @@ -148,7 +188,7 @@ static void *ldapgroup_enumfirst(BOOL update) static void ldapgroup_enumclose(void *vp) { - ldap_close_connection(); + ldap_disconnect(); } @@ -178,7 +218,7 @@ static DOMAIN_GRP *ldapgroup_getgrpbynam(const char *name, fstring filter; DOMAIN_GRP *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return (False); slprintf(filter, sizeof(filter)-1, @@ -187,7 +227,7 @@ static DOMAIN_GRP *ldapgroup_getgrpbynam(const char *name, ret = ldapgroup_getgrp(&domgrp, members, num_membs); - ldap_close_connection(); + ldap_disconnect(); return ret; } @@ -197,7 +237,7 @@ static DOMAIN_GRP *ldapgroup_getgrpbygid(gid_t grp_id, fstring filter; DOMAIN_GRP *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return (False); slprintf(filter, sizeof(filter)-1, @@ -206,7 +246,7 @@ static DOMAIN_GRP *ldapgroup_getgrpbygid(gid_t grp_id, ret = ldapgroup_getgrp(&domgrp, members, num_membs); - ldap_close_connection(); + ldap_disconnect(); return ret; } @@ -216,16 +256,16 @@ static DOMAIN_GRP *ldapgroup_getgrpbyrid(uint32 grp_rid, fstring filter; DOMAIN_GRP *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return (False); slprintf(filter, sizeof(filter)-1, - "(&(rid=%d)(objectClass=sambaGroup))", grp_rid); + "(&(rid=%x)(objectClass=sambaGroup))", grp_rid); ldap_search_for(filter); ret = ldapgroup_getgrp(&domgrp, members, num_membs); - ldap_close_connection(); + ldap_disconnect(); return ret; } @@ -237,13 +277,19 @@ static DOMAIN_GRP *ldapgroup_getcurrentgrp(void *vp, /************************************************************************* - Add/modify domain groups. + Add/modify/delete domain groups. *************************************************************************/ static BOOL ldapgroup_addgrp(DOMAIN_GRP *group) { LDAPMod **mods; + if (!ldap_allocaterid(&group->rid)) + { + DEBUG(0,("RID generation failed\n")); + return (False); + } + ldapgroup_grpmods(group, &mods, LDAP_MOD_ADD); return ldap_makemods("cn", group->name, mods, True); } @@ -256,6 +302,69 @@ static BOOL ldapgroup_modgrp(DOMAIN_GRP *group) return ldap_makemods("cn", group->name, mods, False); } +static BOOL ldapgroup_delgrp(uint32 grp_rid) +{ + fstring filter; + char *dn; + int err; + + if (!ldap_connect()) + return (False); + + slprintf(filter, sizeof(filter)-1, + "(&(rid=%x)(objectClass=sambaGroup))", grp_rid); + ldap_search_for(filter); + + if (!ldap_entry || !(dn = ldap_get_dn(ldap_struct, ldap_entry))) + { + ldap_disconnect(); + return (False); + } + + err = ldap_delete_s(ldap_struct, dn); + free(dn); + ldap_disconnect(); + + if (err != LDAP_SUCCESS) + { + DEBUG(0, ("delete: %s\n", ldap_err2string(err))); + return (False); + } + + return True; +} + + +/************************************************************************* + Add users to/remove users from groups. + *************************************************************************/ + +static BOOL ldapgroup_addmem(uint32 grp_rid, uint32 user_rid) +{ + LDAPMod **mods; + fstring rid_str; + + slprintf(rid_str, sizeof(rid_str)-1, "%x", grp_rid); + + if(!ldapgroup_memmods(user_rid, &mods, LDAP_MOD_ADD)) + return (False); + + return ldap_makemods("rid", rid_str, mods, False); +} + +static BOOL ldapgroup_delmem(uint32 grp_rid, uint32 user_rid) +{ + LDAPMod **mods; + fstring rid_str; + + slprintf(rid_str, sizeof(rid_str)-1, "%x", grp_rid); + + if(!ldapgroup_memmods(user_rid, &mods, LDAP_MOD_DELETE)) + return (False); + + return ldap_makemods("rid", rid_str, mods, False); +} + /************************************************************************* Return domain groups that a user is in. @@ -268,14 +377,18 @@ static BOOL ldapgroup_getusergroups(const char *name, DOMAIN_GRP **groups, fstring filter; int i; + if(!ldap_connect()) + return (False); + slprintf(filter, sizeof(pstring)-1, - "(&(uidMember=%s)(objectclass=sambaGroup))", name); + "(&(member=%s,*)(objectclass=sambaGroup))", name); ldap_search_for(filter); *num_grps = i = ldap_count_entries(ldap_struct, ldap_results); if(!i) { *groups = NULL; + ldap_disconnect(); return (True); } @@ -284,6 +397,7 @@ static BOOL ldapgroup_getusergroups(const char *name, DOMAIN_GRP **groups, i--; } while(ldapgroup_getgrp(&grouplist[i], NULL, NULL) && (i > 0)); + ldap_disconnect(); return (True); } @@ -302,6 +416,10 @@ static struct groupdb_ops ldapgroup_ops = ldapgroup_addgrp, ldapgroup_modgrp, + ldapgroup_delgrp, + + ldapgroup_addmem, + ldapgroup_delmem, ldapgroup_getusergroups }; diff --git a/source3/include/proto.h b/source3/include/proto.h index fc1e2926a81..ee92f62c231 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1375,13 +1375,14 @@ BOOL pm_process( char *FileName, /*The following definitions come from passdb/ldap.c */ -BOOL ldap_open_connection(BOOL modify); -void ldap_close_connection(void); +BOOL ldap_connect(void); +void ldap_disconnect(void); BOOL ldap_search_for(char *filter); BOOL ldap_search_by_name(const char *user); BOOL ldap_search_by_uid(int uid); BOOL ldap_get_attribute(char *attribute, char *value); struct smb_passwd *ldap_getpw(void); +BOOL ldap_allocaterid(uint32 *rid); struct smb_passdb_ops *ldap_initialise_password_db(void); /*The following definitions come from passdb/nispass.c */ diff --git a/source3/passdb/ldap.c b/source3/passdb/ldap.c index 49f7e1d13a1..fad67cb79f6 100644 --- a/source3/passdb/ldap.c +++ b/source3/passdb/ldap.c @@ -43,7 +43,7 @@ static pstring ldap_secret; Open connections to the LDAP server. ******************************************************************/ -BOOL ldap_open_connection(BOOL modify) +BOOL ldap_connect(void) { int err; @@ -66,7 +66,7 @@ BOOL ldap_open_connection(BOOL modify) close connections to the LDAP server. ******************************************************************/ -void ldap_close_connection(void) +void ldap_disconnect(void) { if(!ldap_struct) return; @@ -171,7 +171,7 @@ struct smb_passwd *ldap_getpw(void) return NULL; } smbpw.unix_uid = atoi(temp); - if(ldap_get_attribute("ntuid", nt_name)) { + if(!ldap_get_attribute("ntuid", nt_name)) { DEBUG(0,("Missing ntuid\n")); return NULL; } smbpw.nt_name = nt_name; @@ -179,7 +179,7 @@ struct smb_passwd *ldap_getpw(void) if(!ldap_get_attribute("rid", temp)) { DEBUG(0,("Missing rid\n")); return NULL; } - smbpw.user_rid = atoi(temp); + smbpw.user_rid = strtol(temp, NULL, 16); if(ldap_get_attribute("acctFlags", temp)) smbpw.acct_ctrl = pwdb_decode_acct_ctrl(temp); @@ -206,7 +206,6 @@ struct smb_passwd *ldap_getpw(void) else smbpw.pass_last_set_time = (time_t)(-1); - ldap_entry = ldap_next_entry(ldap_struct, ldap_entry); return &smbpw; } @@ -279,7 +278,7 @@ struct smb_passwd *ldap_getpw(void) ldap_make_mod(mods, LDAP_MOD_ADD, "uidNumber", temp); ldap_make_mod(mods, LDAP_MOD_ADD, "ntuid", newpwd->nt_name); - slprintf(temp, sizeof(temp)-1, "%d", newpwd->user_rid); + slprintf(temp, sizeof(temp)-1, "%x", newpwd->user_rid); ldap_make_mod(mods, LDAP_MOD_ADD, "rid", temp); } @@ -312,44 +311,112 @@ struct smb_passwd *ldap_getpw(void) *************************************************************************/ BOOL ldap_makemods(char *attribute, char *value, LDAPMod **mods, BOOL add) { - pstring dn; + pstring filter; + char *dn; int entries; int err = 0; BOOL rc; - slprintf(dn, sizeof(dn)-1, "%s=%s, %s", attribute, value, - lp_ldap_suffix()); + slprintf(filter, sizeof(filter)-1, "%s=%s", attribute, value); - if(!ldap_open_connection(True)) + if (!ldap_connect()) return (False); - if(add) - err = ldap_add_s(ldap_struct, dn, mods); + ldap_search_for(filter); - if(!add || (err = LDAP_ALREADY_EXISTS)) + if (ldap_entry) + { + dn = ldap_get_dn(ldap_struct, ldap_entry); err = ldap_modify_s(ldap_struct, dn, mods); + free(dn); + } + else if (add) + { + pstrcat(filter, ", "); + pstrcat(filter, lp_ldap_suffix()); + err = ldap_add_s(ldap_struct, filter, mods); + } - if(err == LDAP_SUCCESS) { - DEBUG(2,("Updated entry [%s]\n",value)); + if (err == LDAP_SUCCESS) + { + DEBUG(2,("Updated entry [%s]\n", value)); rc = True; } else { DEBUG(0,("update: %s\n", ldap_err2string(err))); rc = False; } - ldap_close_connection(); + ldap_disconnect(); ldap_mods_free(mods, 1); return rc; } +/************************************************************************ + Return next available RID, starting from 1000 + ************************************************************************/ + +BOOL ldap_allocaterid(uint32 *rid) +{ + pstring newdn; + fstring rid_str; + LDAPMod **mods; + char *dn; + int err; + + DEBUG(2, ("Allocating new RID\n")); + + if (!ldap_connect()) + return (False); + + ldap_search_for("(&(id=root)(objectClass=sambaConfig))"); + + if (ldap_entry && ldap_get_attribute("nextrid", rid_str)) + *rid = strtol(rid_str, NULL, 16); + else + *rid = 1000; + + mods = NULL; + if(!ldap_entry) + { + ldap_make_mod(&mods, LDAP_MOD_ADD, "objectClass", + "sambaConfig"); + ldap_make_mod(&mods, LDAP_MOD_ADD, "id", "root"); + } + + slprintf(rid_str, sizeof(fstring)-1, "%x", (*rid) + 1); + ldap_make_mod(&mods, LDAP_MOD_REPLACE, "nextrid", rid_str); + + if (ldap_entry) + { + dn = ldap_get_dn(ldap_struct, ldap_entry); + err = ldap_modify_s(ldap_struct, dn, mods); + free(dn); + } else { + pstrcpy(newdn, "id=root, "); + pstrcat(newdn, lp_ldap_suffix()); + ldap_add_s(ldap_struct, newdn, mods); + } + + ldap_disconnect(); + + if(err != LDAP_SUCCESS) + { + DEBUG(0,("nextrid update: %s\n", ldap_err2string(err))); + return (False); + } + + return (True); +} + + /*************************************************************** Begin/end account enumeration. ****************************************************************/ static void *ldap_enumfirst(BOOL update) { - if (!ldap_open_connection(False)) + if (!ldap_connect()) return NULL; ldap_search_for("objectclass=sambaAccount"); @@ -359,7 +426,7 @@ static void *ldap_enumfirst(BOOL update) static void ldap_enumclose(void *vp) { - ldap_close_connection(); + ldap_disconnect(); } @@ -387,13 +454,13 @@ static struct smb_passwd *ldap_getpwbynam(const char *name) { struct smb_passwd *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return NULL; ldap_search_by_name(name); ret = ldap_getpw(); - ldap_close_connection(); + ldap_disconnect(); return ret; } @@ -401,19 +468,23 @@ static struct smb_passwd *ldap_getpwbyuid(uid_t userid) { struct smb_passwd *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return NULL; ldap_search_by_uid(userid); ret = ldap_getpw(); - ldap_close_connection(); + ldap_disconnect(); return ret; } static struct smb_passwd *ldap_getcurrentpw(void *vp) { - return ldap_getpw(); + struct smb_passwd *ret; + + ret = ldap_getpw(); + ldap_entry = ldap_next_entry(ldap_struct, ldap_entry); + return ret; } @@ -424,6 +495,9 @@ static BOOL ldap_addpw(struct smb_passwd *newpwd) { LDAPMod **mods; + if (!newpwd || !ldap_allocaterid(&newpwd->user_rid)) + return (False); + ldap_smbpwmods(newpwd, &mods, LDAP_MOD_ADD); return ldap_makemods("uid", newpwd->unix_name, mods, True); } @@ -432,6 +506,9 @@ static BOOL ldap_modpw(struct smb_passwd *pwd, BOOL override) { LDAPMod **mods; + if (!pwd) + return (False); + ldap_smbpwmods(pwd, &mods, LDAP_MOD_REPLACE); return ldap_makemods("uid", pwd->unix_name, mods, False); } diff --git a/source3/passdb/passgrpldap.c b/source3/passdb/passgrpldap.c index 3d647cd7763..1092a3c5b16 100644 --- a/source3/passdb/passgrpldap.c +++ b/source3/passdb/passgrpldap.c @@ -66,7 +66,7 @@ static void ldappassgrp_member(char *attribute, uint32 **rids, int *numrids) static void *ldappassgrp_enumfirst(BOOL update) { - if (!ldap_open_connection(False)) + if (!ldap_connect()) return NULL; ldap_search_for("&(objectclass=sambaAccount)(|(group=*)(alias=*))"); @@ -76,7 +76,7 @@ static void *ldappassgrp_enumfirst(BOOL update) static void ldappassgrp_enumclose(void *vp) { - ldap_close_connection(); + ldap_disconnect(); } @@ -106,7 +106,7 @@ static struct smb_passwd *ldappassgrp_getpwbynam(const char *name, { struct smb_passwd *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return NULL; ldap_search_by_ntname(name); @@ -114,7 +114,7 @@ static struct smb_passwd *ldappassgrp_getpwbynam(const char *name, ldappassgrp_member("alias", als_rids, num_alss); ret = ldap_getpw(); - ldap_close_connection(); + ldap_disconnect(); return ret; } @@ -124,7 +124,7 @@ static struct smb_passwd *ldappassgrp_getpwbyuid(uid_t userid, { struct smb_passwd *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return NULL; ldap_search_by_uid(userid); @@ -132,7 +132,7 @@ static struct smb_passwd *ldappassgrp_getpwbyuid(uid_t userid, ldappassgrp_member("alias", als_rids, num_alss); ret = ldap_getpw(); - ldap_close_connection(); + ldap_disconnect(); return ret; } @@ -142,7 +142,7 @@ static struct smb_passwd *ldappassgrp_getpwbyrid(uint32 user_rid, { struct smb_passwd *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return NULL; ldap_search_by_rid(user_rid); @@ -150,7 +150,7 @@ static struct smb_passwd *ldappassgrp_getpwbyrid(uint32 user_rid, ldappassgrp_member("alias", als_rids, num_alss); ret = ldap_getpw(); - ldap_close_connection(); + ldap_disconnect(); return ret; } diff --git a/source3/passdb/sampassldap.c b/source3/passdb/sampassldap.c index 1c3283df0fd..e456b6ab435 100644 --- a/source3/passdb/sampassldap.c +++ b/source3/passdb/sampassldap.c @@ -30,9 +30,9 @@ extern int DEBUGLEVEL; /* Internal state */ -LDAP *ldap_struct; -LDAPMessage *ldap_results; -LDAPMessage *ldap_entry; +extern LDAP *ldap_struct; +extern LDAPMessage *ldap_results; +extern LDAPMessage *ldap_entry; /******************************************************************* @@ -44,7 +44,7 @@ BOOL ldap_search_by_rid(uint32 rid) fstring filter; slprintf(filter, sizeof(filter)-1, - "(&(rid=%d)(objectclass=sambaAccount))", rid); + "(&(rid=%x)(objectclass=sambaAccount))", rid); return ldap_search_for(filter); } @@ -120,7 +120,7 @@ static struct sam_passwd *ldapsam_getsam() sam21->unix_gid = (gid_t)(-1); if(ldap_get_attribute("grouprid", temp)) - sam21->group_rid = atoi(temp); + sam21->group_rid = strtol(temp, NULL, 16); else sam21->group_rid = 0xFFFFFFFF; @@ -174,6 +174,7 @@ static struct sam_passwd *ldapsam_getsam() sam21->unknown_str = NULL; sam21->munged_dial = NULL; + ldap_entry = ldap_next_entry(ldap_struct, ldap_entry); return sam21; } @@ -201,7 +202,7 @@ static struct sam_disp_info *ldapsam_getdispinfo() DEBUG(2,("Retrieving account [%s]\n",nt_name)); if(ldap_get_attribute("rid", temp)) - dispinfo.user_rid = atoi(temp); + dispinfo.user_rid = strtol(temp, NULL, 16); else { DEBUG(0,("Missing rid\n")); return NULL; } @@ -211,6 +212,7 @@ static struct sam_disp_info *ldapsam_getdispinfo() else dispinfo.full_name = NULL; + ldap_entry = ldap_next_entry(ldap_struct, ldap_entry); return &dispinfo; } @@ -231,7 +233,7 @@ static void ldapsam_sammods(struct sam_passwd *newpwd, LDAPMod ***mods, slprintf(temp, sizeof(temp)-1, "%d", newpwd->unix_gid); ldap_make_mod(mods, operation, "gidNumber", temp); - slprintf(temp, sizeof(temp)-1, "%d", newpwd->group_rid); + slprintf(temp, sizeof(temp)-1, "%x", newpwd->group_rid); ldap_make_mod(mods, operation, "grouprid", temp); ldap_make_mod(mods, operation, "cn", newpwd->full_name); @@ -261,7 +263,7 @@ static void ldapsam_sammods(struct sam_passwd *newpwd, LDAPMod ***mods, static void *ldapsam_enumfirst(BOOL update) { - if (!ldap_open_connection(False)) + if (!ldap_connect()) return NULL; ldap_search_for("objectclass=sambaAccount"); @@ -271,7 +273,7 @@ static void *ldapsam_enumfirst(BOOL update) static void ldapsam_enumclose(void *vp) { - ldap_close_connection(); + ldap_disconnect(); } @@ -299,13 +301,13 @@ static struct sam_passwd *ldapsam_getsambynam(const char *name) { struct sam_passwd *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return NULL; ldap_search_by_ntname(name); ret = ldapsam_getsam(); - ldap_close_connection(); + ldap_disconnect(); return ret; } @@ -313,13 +315,13 @@ static struct sam_passwd *ldapsam_getsambyuid(uid_t userid) { struct sam_passwd *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return NULL; ldap_search_by_uid(userid); ret = ldapsam_getsam(); - ldap_close_connection(); + ldap_disconnect(); return ret; } @@ -327,13 +329,13 @@ static struct sam_passwd *ldapsam_getsambyrid(uint32 user_rid) { struct sam_passwd *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return NULL; ldap_search_by_rid(user_rid); ret = ldapsam_getsam(); - ldap_close_connection(); + ldap_disconnect(); return ret; } @@ -351,6 +353,9 @@ static BOOL ldapsam_addsam(struct sam_passwd *newpwd) { LDAPMod **mods; + if (!newpwd || !ldap_allocaterid(&newpwd->user_rid)) + return (False); + ldapsam_sammods(newpwd, &mods, LDAP_MOD_ADD); return ldap_makemods("uid", newpwd->unix_name, mods, True); } @@ -359,6 +364,9 @@ static BOOL ldapsam_modsam(struct sam_passwd *pwd, BOOL override) { LDAPMod **mods; + if (!pwd) + return (False); + ldapsam_sammods(pwd, &mods, LDAP_MOD_REPLACE); return ldap_makemods("uid", pwd->unix_name, mods, False); } @@ -372,13 +380,13 @@ static struct sam_disp_info *ldapsam_getdispbynam(const char *name) { struct sam_disp_info *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return NULL; ldap_search_by_ntname(name); ret = ldapsam_getdispinfo(); - ldap_close_connection(); + ldap_disconnect(); return ret; } @@ -386,13 +394,13 @@ static struct sam_disp_info *ldapsam_getdispbyrid(uint32 user_rid) { struct sam_disp_info *ret; - if(!ldap_open_connection(False)) + if(!ldap_connect()) return NULL; ldap_search_by_rid(user_rid); ret = ldapsam_getdispinfo(); - ldap_close_connection(); + ldap_disconnect(); return ret; }