Finally committing my LDAP changes.
authorMatthew Chapman <matty@samba.org>
Fri, 15 Jan 1999 05:00:26 +0000 (05:00 +0000)
committerMatthew Chapman <matty@samba.org>
Fri, 15 Jan 1999 05:00:26 +0000 (05:00 +0000)
* 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 <allan@umich.edu>:
   - 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 <mh@bacher.at>
   - 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)

source3/groupdb/aliasldap.c
source3/groupdb/builtinldap.c
source3/groupdb/groupldap.c
source3/include/proto.h
source3/passdb/ldap.c
source3/passdb/passgrpldap.c
source3/passdb/sampassldap.c

index 35d810dabc23cd40b471d3f701313c6e652b8205..1e9a72a9d415401c3a9214ecc265cb2fcf5923a1 100644 (file)
@@ -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
 };
index f2a530cbb95fe534d7af2d58cad145a99755ced1..baac82f1bab63be1644edc9aeef1a04dd9b36a54 100644 (file)
@@ -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
 };
index df0d7552402007690d25f5b5444a1e52f73d05d6..4411ead14ca7835901b707da7f590dee3cba46d1 100644 (file)
@@ -28,6 +28,7 @@
 #include <ldap.h>
 
 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
 };
index fc1e2926a815dcc754436266329a774ee9d606b3..ee92f62c231a1312646c32114355180860d9baf3 100644 (file)
@@ -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  */
index 49f7e1d13a1b565d01c62fe6cecfbd3c85dca63a..fad67cb79f6348e2615fd2051ff9253ed3ff4e3b 100644 (file)
@@ -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);
 }
index 3d647cd77633fd3ae20bf81a4b18c3808317b2e8..1092a3c5b16804ae0f76b698969c81a4c35467c0 100644 (file)
@@ -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;
 }
 
index 1c3283df0fde1ae12e61aa9b8cdb53f1e312bae4..e456b6ab4354497a797bf9bf048313881189dd65 100644 (file)
@@ -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;
 }