Open Source Development

Power Open Source Development

Explore the open source tools and capabilities for building and deploying modern applications on IBM Power platforms including AIX, IBM i, and Linux.


#Power


#Power

 View Only

Samba / WINBIND getgracct doesn't work

  • 1.  Samba / WINBIND getgracct doesn't work

    Posted 2 days ago
    Edited by Lorraine Rizzuto yesterday
    At current levels of AIX (7.2tl5-sp9 and above, 7.3tl2-sp3 and above, 7.3tl3) there was a code change so that a call to getgrgid might decide to utilize a load module's built-in getgracct function.
     
    As it turns out, WINBIND's getgracct function doesn't work, so now group resolution can fail. 
    For example, a user that should have several secondary groups, like this:
     
    # id LABAD+ldapnick
    uid=10000(LABAD+ldapnick) gid=10000(LABAD+domain users) groups=10020(LABAD+$mn1000-pdrphuveqogl),10019(LABAD+$181000-v9grkvschj0f),10018(LABAD+wseallowaddinaccess),10017(LABAD+wseallowhomepagelinks),10016(LABAD+wseremoteaccessusers),...etc...
     
     
    After an upgrade to 7.2tl5-sp9, we'll only see:
    # id LABAD+ldapnick
    uid=10000(LABAD+ldapnick) gid=10000(LABAD+domain users)
     
    Debugging of AIX show us that WINBIND's method_getgracct is returning ENOENT / not found.
     
     
     
    I downloaded the current samba / winbind source rpm from our Toolbox.
    This is the WINBIND module's method_getgracct function:
     
    static struct group *wb_aix_getgracct(void *id, int type)
    {
            if (type == 1) {
                    return wb_aix_getgrnam((char *)id);
            }
            if (type == 0) {
                    return wb_aix_getgrgid(*(int *)id);
            }
            errno = EINVAL;
            return NULL;
    }
     
    All it does is - if called with type=0, it calls its own getgrgid function. So even if the getgracct is called, it ends up going through getgrgid anyway.
     
     
    Problem is - this is what happens when WINBIND getgracct is called:
     
    wb_aix_getgrgid(0x0) at 0xddf62900
    wb_aix_getgracct(0x2723, 0x0) at 0xddf62cc0
    _getgrgid_r(gid = 10019, grp_ptr = 0x2ff1dbd8, line = "", line_len = 20023, no_big_buf = 1, need_mem = 0), line 1147 in "getgrent.c"
     
     
    ...it calls its own getgrgid function with a null argument instead of the 10019 / 0x2723 group number that we are wanting to look up. That '*(int *)id' isn't working too well.
     
    It looks like it should be doing:
     
    return wb_aix_getgrgid((int) id);
     
    I've done some tests with a small test program that calls similarly-defined functions and verified that change works:
     
    Before the change:
     
    # ./getgr 10020 0
    calling mygracct with 10020 0x2724
    inside mygracct, we have 10020 0x2724
    inside mygrgid, we have 0 0x0
     
    ^^^ same behavior WINBIND sees
     
     
    After the change:
     
    # ./getgr 10020 0
    calling mygracct with 10020 0x2724
    inside mygracct, we have 10020 0x2724
    inside mygrgid, we have 10020 0x2724
     
     
    ^^^ the GID number is successfully passed
     
    The call that wb_aix_getgracct makes to wb_aix_getgrnam looks like it is fine as it is:
     
    # ./getgr MyGroup 1
    calling mygracct with MyGroup
    inside mygracct, we have 804400272 0x2ff22c90
    inside mygrnam, we have MyGroup
     
     
     
    The test program I used is:
     
    #include <stdio.h>
    #include <stdlib.h>
     
    void *mygracct (void *id, int type);
    void *mygrgid (int gid);
    void *mygrnam (char *name);
     
    void main (int argc, char * argv[]) {
            if(atoi(argv[2])==0) {
                    printf("calling mygracct with %d 0x%x\n",atoi(argv[1]),atoi(argv[1]));
                    mygracct((void *) atoi(argv[1]),0);
            }
            else {
                    printf("calling mygracct with %s\n",argv[1]);
                    mygracct(argv[1],1);
            }
    }
     
    void *mygracct (void *id, int type) {
            printf("inside mygracct, we have %d 0x%x\n",id,id);
     
            if(type==0) mygrgid((int) id);  /* fixed from (*(int *)id) */
            else mygrnam((char *) id);
    }
     
    void *mygrgid (int gid) {
            printf ("inside mygrgid, we have %d 0x%x\n",gid,gid);
    }
     
    void *mygrnam (char * name) {
            printf("inside mygrnam, we have %s\n",name);
    }
     



    ------------------------------
    Nick Kennedy
    ------------------------------