[Samba] [PATCH] Group mapping primary group SID update

Ganael Laplanche ganael.laplanche at martymac.com
Fri Jan 30 09:18:46 GMT 2004


Hi all !

This is a patch for Group mapping bug #1 reported here :
http://lists.samba.org/archive/samba-technical/2004-January/034057.html

It activates users' primary group SID update when adding/modifying/deleting a
group mapping. It patches utils/net_groupmap.c (net_groupmap_add,
net_groupmap_modify, net_groupmap_delete) and can be applied to samba-3.0.2rc1.

net_groupmap_add :
Scan users having the *new* Unix gid mapped as primary group and update their
primaryGroupSid info in passdb.

net_groupmap_modify :
Scan users having the *old* Unix gid mapped as primary group and update their
primaryGroupSid info in passdb by computing it.
Scan users having the *new* Unix gid mapped as primary group and update their
primaryGroupSid info in passdb.

net_groupmap_delete :
Scan users having the *old* Unix gid mapped as primary group and update their
primaryGroupSid info in passdb by computing it.

!!!NOTE!!! : THIS PATCH DOESNT WORK WITH TDB BACKEND, but it works perfectly
with ldap backend. Since I'm not a Samba guru, I couldn't make this patch work
with TDB backend. I think it is very simple to fix : the problem is pdb_ldap and
pdb_tdb doesn't update sam account the same way : pdb_tdb.c invalidates the
iterator during a sam update (while pdb_ldap doesn't), so the main loop crashes
after the first pdb_update_sam_account while trying to use pdb_getsampwent. The
patch may be easy to fix and can be a good start for an final bugfix.

--------------------- Start of updatesid.patch ---------------------
--- utils/net_groupmap.c.orig   2003-09-24 19:16:13.000000000 +0200
+++ utils/net_groupmap.c        2004-01-29 13:38:06.000000000 +0100
@@ -80,6 +80,65 @@
        return True;
 }

+/******************************************************
+ Update primary group SID in passdb with <string_sid>
+ for users whose Unix primary group is <gid>. Useful 
+ after a net_groupmap add/modify/delete.
+******************************************************/
+static BOOL update_users_primgroup_sid(const gid_t gid,  fstring string_sid)
+{
+       SAM_ACCOUNT *sam_pwent=NULL; 
+       struct passwd *pass=NULL;
+       fstring usrname = "";
+
+       /* Initialize static context */
+       if(!initialize_password_db(True)) {
+               DEBUG(0,("update_users_primgroup_sid: Cannot initialize password
database.\n"));
+               return False;
+       }
+       /* Open password database for update */
+       if(!pdb_setsampwent(True)) {
+               DEBUG(0,("update_users_primgroup_sid: Cannot open password
database.\n"));
+               return False;
+       }
+
+       while (NT_STATUS_IS_OK(pdb_init_sam(&sam_pwent)) &&
pdb_getsampwent(sam_pwent)) {
+               fstrcpy(usrname,pdb_get_username(sam_pwent));
+               if(!(pass = Get_Pwnam(usrname))) {
+                       DEBUG(0,("update_users_primgroup_sid: Cannot find Unix
account for %s.\n", usrname));
+                       return False;
+               }
+
+               if ((pass->pw_gid) != (gid_t)-1) {
+                       /* Check if user's primary group SID must be updated (if
mapped gid is the user's primary group gid) */
+                       if (pass->pw_gid == gid) {
+                               if (string_sid) { /* String specified, use it */
+                                       pdb_set_group_sid_from_string(sam_pwent,
string_sid, PDB_CHANGED);
+                               }
+                               else { /* no string specified, must compute the
RID */
+                                       pdb_set_group_sid_from_rid(sam_pwent,
pdb_gid_to_group_rid(pass->pw_gid), PDB_CHANGED);
+                               }
+
+                               /* Commit changes */
+                               if (pdb_update_sam_account(sam_pwent)) {
+                                       /* Works well with pdb LDAP, BUT
!!Error!! while using pdb TDB : pdb_tdb.c invalidates
+                                       the iterator in tdb_update_sam (called
by pdb_update_sam_account). The result is
+                                       an iterator error in the next
pdb_getsampwent of the loop. MUST BE CORRECTED*/
+                                       d_printf("Successully updated primary
group SID for user %s\n", usrname);
+                               }
+                               else {
+                                       d_printf("Could not update primary group
SID for user %s\n", usrname);
+                               }
+                       }
+               }
+               pdb_free_sam(&sam_pwent);
+       }
+       pdb_free_sam(&sam_pwent);
+       pdb_endsampwent();
+
+       return True;
+}
+
 /*********************************************************
  Dump a GROUP_MAP entry to stdout (long or short listing)
 **********************************************************/
@@ -287,6 +346,9 @@
        }

        d_printf("Successully added group %s to the mapping db\n", ntgroup);
+
+       update_users_primgroup_sid(gid, string_sid);
+
        return 0;
 }

@@ -303,6 +365,9 @@
        int i;
        gid_t gid;

+       gid_t old_gid;
+       fstring usrsid = "";
+
        /* get the options */
        for ( i=0; i<argc; i++ ) {
                if ( !StrnCaseCmp(argv[i], "ntgroup", strlen("ntgroup")) ) {
@@ -398,6 +463,8 @@
        if ( ntgroup[0] )
                fstrcpy( map.nt_name, ntgroup );

+       /* Keep old gid in memory then change it if needed */
+       old_gid = map.gid;
        if ( unixgrp[0] ) {
                gid = nametogid( unixgrp );
                if ( gid == -1 ) {
@@ -416,6 +483,16 @@

        d_printf("Updated mapping entry for %s\n", ntgroup);

+       /* If gid changed we may need to update user SIDs */
+       if(old_gid != map.gid) {
+               /* Compute primary group SID for users belonging to the old gid
that is no longer mapped */
+               update_users_primgroup_sid(old_gid, NULL);
+
+               /* Update primary group SID for users belonging to the new gid
mapped to the existing SID */
+               sid_to_string(usrsid, &sid);
+               update_users_primgroup_sid(gid, usrsid);
+       }
+
        return 0;
 }

@@ -426,6 +503,9 @@
        fstring sid_string = "";
        int i;

+       gid_t old_gid;
+       fstring usrsid = "";
+
        /* get the options */
        for ( i=0; i<argc; i++ ) {
                if ( !StrnCaseCmp(argv[i], "ntgroup", strlen("ntgroup")) ) {
@@ -463,6 +543,13 @@
                return -1;
        }

+       /* Keep in memory the old gid */
+       if (!NT_STATUS_IS_OK(sid_to_gid(&sid, &old_gid)) ) {
+               sid_to_string(usrsid, &sid);
+               d_printf("Unable to resolve SID %s to gid\n", usrsid);
+               return -1;
+       }
+
        if ( !pdb_delete_group_mapping_entry(sid) ) {
                printf("Failed to removing group %s from the mapping db!\n",
ntgroup);
                return -1;
@@ -470,6 +557,9 @@

        d_printf("Sucessfully removed %s from the mapping db\n", ntgroup);

+       /* Compute primary group SID for users belonging to the old gid that is
no longer mapped */
+       update_users_primgroup_sid(old_gid, NULL);
+
        return 0;
 }
--------------------- End of updatesid.patch ---------------------

I hope this work will be useful, any comment welcome :)

Regards,

Ganaël LAPLANCHE
ganael.laplanche at martymac.com
http://www.martymac.com
Tel : (+33)6.84.03.57.24.




More information about the samba mailing list