Ganael Laplanche
2004-Jan-30 09:16 UTC
[Samba] [PATCH] Group mapping primary group SID update
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@martymac.com http://www.martymac.com Tel : (+33)6.84.03.57.24.
Possibly Parallel Threads
- OpenSSH-3.9p1 permanently_set_uid behavior on Linux
- [PATCH] permanently_set_uid: Don't try restoring gid on Cygwin
- Question about a recent change to uidswap.c in the portability snapshot
- uidswap.c breaks ssh when originating user is root
- Patches for samba 3.0.0 client/client.c