Bug 400 - setauthdb need to invoked before every getpwnam() / getpwuid() call on AIX
setauthdb need to invoked before every getpwnam() / getpwuid() call on AIX
Status: RESOLVED FIXED
Product: Sudo
Classification: Unclassified
Component: Sudo
1.7.2
IBM AIX
: normal normal
Assigned To: Todd C. Miller
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2010-03-24 14:21 MDT by Yannick Bergeron
Modified: 2010-07-20 13:52 MDT (History)
0 users

See Also:


Attachments
aix.c : aix_restoreauthdb modified (1.04 KB, patch)
2010-07-20 12:21 MDT, karl
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Yannick Bergeron 2010-03-24 14:21:37 MDT
explanation of the issue

user1 is defined in /etc/security/user to be in backend A (SYSTEM and registry)
user1 only exist in backend A
user2 is defined in /etc/security/user to be in backend B (SYSTEM and registry)
but user2 exist in both backend A and backend B

As user1, if I issue the command "sudo -u user2 id", I should see uid,gid and groups related to user2 in backend B
But because user1 is in backend A, sudo is fetching these informations from backend A instead.

By adding the wrappers, sudo will fetch the information from the backend user2 is defined on, which is backend B in this example

########

Wrappers need to be added around getpwnam() and getpwuid() call on AIX. This wrapper consist in;

Before the call to getpwnam()/getpwuid():
setuserdb // open userdb read-only
getuserattr // get user registry
setauthdb // to the new registry returned by getuserattr
enduserdb // close userdb

and after the call
setauthdb // to the old registry value


openssh 5.4p1 has this kind of wrappers defined in openbsd-compat/port-aix.c as aix_setauthdb() and aix_restoreauthdb()
and being used in openssh-5.4p1/auth.c and openbsd-compat/port-aix.c


please let me know if you want/can implement a patch from what is being done in openssh or let us know if you want us to submit our own patch
Comment 1 Todd C. Miller 2010-06-15 12:59:56 MDT
Please give the following a try and see if it works for you: ftp://ftp.sudo.ws/pub/millert/sudo/sudo-1.7.3b3-aix.tar.gz

That version has changes to call setauthdb() based on SYSTEM rather than registry like OpenSSH does.  Can you tell me which approach is best?  The AIX online documentation is unclear on this.
Comment 2 Yannick Bergeron 2010-06-15 13:21:25 MDT
link doesn't work

and http://www.gratisoft.us/sudo/dist/beta/sudo-1.7.3b3.tar.gz
does not include the aix modification you're talking about

can you verify it's available somewhere on the ftp?
Comment 3 Todd C. Miller 2010-06-15 13:57:09 MDT
Sorry about that, I've fixed the link.

ftp://ftp.sudo.ws/pub/millert/sudo/sudo-1.7.3b3-aix.tar.gz
Comment 4 Todd C. Miller 2010-06-16 10:05:12 MDT
The config.h.in file in that tarball is missing the following lines, you will need to add them for configure to enable the setauthdb support.
 
/* Define to 1 if you have the `setauthdb' function. */
#undef HAVE_SETAUTHDB
Comment 5 Yannick Bergeron 2010-06-16 15:04:24 MDT
ok downloaded it, extracted it, added the 2 lines in config.h.in

./configure --prefix=/usr/local/sudo-1.7.3b3 --sysconfdir=/etc
make

following error
        cc -qlanglvl=extc89 -c -I. -I.  -g -D_XOPEN_EXTENDED_SOURCE -D_ALL_SOURCE -D_PATH_SUDOERS=\"/etc/sudoers\" -DSUDOERS_UID=0 -DSUDOERS_GID=0 -DSUDOERS_MODE=0440  ./pwutil.c
"./pwutil.c", line 228.19: 1506-045 (S) Undeclared identifier user.
"./pwutil.c", line 576.23: 1506-022 (S) "pw_user" is not a member of "struct passwd".
make: 1254-004 The error code from the last command is 1.


Stop.

first error fixed with
*** pwutil.c.org        Wed Jun 16 14:56:13 2010
--- pwutil.c    Wed Jun 16 14:56:35 2010
***************
*** 225,231 ****
       * Cache passwd db entry if it exists or a negative response if not.
       */
  #ifdef HAVE_SETAUTHDB
!     aix_setauthdb(user);
  #endif
      if ((pw = getpwnam(name)) != NULL) {
        pw = sudo_pwdup(pw);
--- 225,231 ----
       * Cache passwd db entry if it exists or a negative response if not.
       */
  #ifdef HAVE_SETAUTHDB
!     aix_setauthdb(name);
  #endif
      if ((pw = getpwnam(name)) != NULL) {
        pw = sudo_pwdup(pw);


second error fixed with
*** pwutil.c    Wed Jun 16 14:57:59 2010
--- pwutil.c.org2       Wed Jun 16 14:57:41 2010
***************
*** 573,579 ****
      struct group *grp;

  #ifdef HAVE_SETAUTHDB
!     aix_setauthdb(pw->pw_name);
  #endif
      grp = sudo_getgrnam(group);
  #ifdef HAVE_SETAUTHDB
--- 573,579 ----
      struct group *grp;

  #ifdef HAVE_SETAUTHDB
!     aix_setauthdb(pw->pw_user);
  #endif
      grp = sudo_getgrnam(group);
  #ifdef HAVE_SETAUTHDB



then got errors in aix.c

        cc -qlanglvl=extc89 -c -I. -I.  -g -D_XOPEN_EXTENDED_SOURCE -D_ALL_SOURCE -D_PATH_SUDOERS=\"/etc/sudoers\" -DSUDOERS_UID=0 -DSUDOERS_GID=0 -DSUDOERS_MODE=0440  ./aix.c
"./aix.c", line 166.75: 1506-186 (S) String literal must be ended before the end of line.
"./aix.c", line 167.9: 1506-276 (S) Syntax error: possible missing ')'?
"./aix.c", line 182.45: 1506-045 (S) Undeclared identifier user_ttypath.
"./aix.c", line 182.60: 1506-045 (S) Undeclared identifier user_ttypath.
"./aix.c", line 182.9: 1506-045 (S) Undeclared identifier user.
"./aix.c", line 182.21: 1506-045 (S) Undeclared identifier user.
"./aix.c", line 182.33: 1506-045 (S) Undeclared identifier user.
"./aix.c", line 183.19: 1506-045 (S) Undeclared identifier SETUINFO.
"./aix.c", line 194.30: 1506-204 (S) Unexpected end of file.
make: 1254-004 The error code from the last command is 1.

fix
--- aix.c       Wed Jun 16 14:59:35 2010
***************
*** 163,169 ****
  {
      if (saved_authsys[0]) {
        if (setauthdb(saved_authsys, NULL) != 0)
!           error(1, "unable to restore authsystem \"%s\", saved_authsys);
        saved_authsys[0] = '\0';
      }
  }
--- 163,169 ----
  {
      if (saved_authsys[0]) {
        if (setauthdb(saved_authsys, NULL) != 0)
!           error(1, "unable to restore authsystem \"%s\"", saved_authsys);
        saved_authsys[0] = '\0';
      }
  }


now getting
        cc -qlanglvl=extc89 -c -I. -I.  -g -D_XOPEN_EXTENDED_SOURCE -D_ALL_SOURCE -D_PATH_SUDOERS=\"/etc/sudoers\" -DSUDOERS_UID=0 -DSUDOERS_GID=0 -DSUDOERS_MODE=0440  ./aix.c
"./aix.c", line 182.45: 1506-045 (S) Undeclared identifier user_ttypath.
"./aix.c", line 182.60: 1506-045 (S) Undeclared identifier user_ttypath.
"./aix.c", line 183.19: 1506-045 (S) Undeclared identifier SETUINFO.
make: 1254-004 The error code from the last command is 1.

and there I'm not too sure where your user_ttypath comes from...

I'll compare the aix changes you've made between 1.7.2p7 and 1.7.3b3 to understand how you did it. I'll also try to answer to: "That version has changes to call setauthdb() based on SYSTEM rather
than registry like OpenSSH does.  Can you tell me which approach is
best?  The AIX online documentation is unclear on this."
Comment 6 Todd C. Miller 2010-06-16 15:37:54 MDT
I believe I've fixed the compilation problems:
ftp://ftp.sudo.ws/pub/millert/sudo/sudo-1.7.3b3-aix2.tar.gz
Comment 7 Yannick Bergeron 2010-06-16 15:56:07 MDT
now I'm getting

        cc -qlanglvl=extc89 -c -I. -I.  -g -D_XOPEN_EXTENDED_SOURCE -D_ALL_SOURCE -D_PATH_SUDOERS=\"/etc/sudoers\" -DSUDOERS_UID=0 -DSUDOERS_GID=0 -DSUDOERS_MODE=0440  ./iolog.c
"./iolog.c", line 51.11: 1506-296 (S) #include file <zlib.h> not found.
"./iolog.c", line 59.5: 1506-046 (S) Syntax error.
"./iolog.c", line 211.17: 1506-068 (W) Operation between types "void*" and "int" is not allowed.
"./iolog.c", line 312.31: 1506-022 (S) "g" is not a member of "union io_fd".
"./iolog.c", line 334.29: 1506-022 (S) "g" is not a member of "union io_fd".
"./iolog.c", line 343.38: 1506-022 (S) "g" is not a member of "union io_fd".
make: 1254-004 The error code from the last command is 1.


I don't remember that zlib was a prerequisite in 1.7.2p7
I've it installed in /usr/local/zlib so I just did 2 symlink for now to let it find zlib.h and zconf.h

now getting
        cc -qlanglvl=extc89 -c -I. -I.  -g -D_XOPEN_EXTENDED_SOURCE -D_ALL_SOURCE -D_PATH_SUDOERS=\"/etc/sudoers\" -DSUDOERS_UID=0 -DSUDOERS_GID=0 -DSUDOERS_MODE=0440  ./goodpath.c
"./sudo.h", line 241.28: 1506-277 (S) Syntax error: possible missing ')' or ','?
"./sudo.h", line 241.35: 1506-335 (S) Parameter identifier list contains multiple occurrences of fd_set.
"./sudo.h", line 241.5: 1506-282 (S) The type of the parameters must be specified in a prototype.
"./sudo.h", line 243.30: 1506-277 (S) Syntax error: possible missing ')' or ','?
"./sudo.h", line 243.37: 1506-335 (S) Parameter identifier list contains multiple occurrences of fd_set.
"./sudo.h", line 243.6: 1506-282 (S) The type of the parameters must be specified in a prototype.
make: 1254-004 The error code from the last command is 1.

maybe I'll need to define a few more things to get zlib correctly found but it's gonna be tomorrow

if you have any idea, let me know
Comment 8 Todd C. Miller 2010-06-16 16:14:55 MDT
1) it sounds like configure found libz but the header files are not in a standard location.  There is a --disable-zlib configure option to disable use of zlib.  The zlib support is new in sudo 1.7.3.

2) I think the syntax error is the use of fd_set * in two prototypes in sudo.h when included by source files that don't include sys/select.h.  You could just move the prototypes for perform_io() and fd_set_iobs() into exec_pty.c to work around this.
Comment 9 Todd C. Miller 2010-06-16 16:54:30 MDT
I've moved the troublesome prototypes into their own header file and add a check for zlib.h to configure.

ftp://ftp.sudo.ws/pub/millert/sudo/sudo-1.7.3b3-aix3.tar.gz
Comment 10 Yannick Bergeron 2010-06-16 19:09:05 MDT
attempt with your latest b3 and ./configure --prefix=/usr/local/sudo-1.7.3b3 --sysconfdir=/etc --disable-zlib

        cc -qlanglvl=extc89 -o visudo visudo.o fileops.o gettime.o goodpath.o find_path.o -L.  -lsudo
ld: 0711-317 ERROR: Undefined symbol: .aix_setauthdb
ld: 0711-317 ERROR: Undefined symbol: .aix_restoreauthdb
ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information.
make: 1254-004 The error code from the last command is 8.


Stop.
Comment 11 Todd C. Miller 2010-06-16 19:55:47 MDT
Try editing the Makefile and moving aix.o from SUDO_OBJS to COMMON_OBJS
Comment 12 Todd C. Miller 2010-06-16 20:07:58 MDT
I've moved aix.o to COMMON_OBJS in ftp://ftp.sudo.ws/pub/millert/sudo/sudo-1.7.3b3-aix4.tar.gz
Comment 13 Yannick Bergeron 2010-06-16 21:25:44 MDT
well some good news before going to bed

with your latest changes, I've been able to complete the compilation and installation.

Did a quick test to see if the issue seems to be fixed and it's looking very good

testcase:
yaberger exist on AIX and DCE
yaberger AIX uid is 919 and gid is 21
yaberger DCE uid is 5427 and gid is 45064
I'm logged as yaberge2 who is a DCE userid
yaberger is configured to authenticate against AIX

known issue is that instead of using yaberger as configured (AIX), it will use the same SYSTEM/registry that yaberge2 is configured with (DCE in this example)

see the issue with 1.7.2p7
yaberge2@aix61tst ==> /usr/local/sudo-1.7.2p7/bin/sudo -u yaberger id
uid=5427(yaberger) gid=45064(yaberger)

and working correctly with 1.7.3b3-aix4
yaberge2@aix61tst ==> /usr/local/sudo-1.7.3b3/bin/sudo -u yaberger id
uid=919(yaberger) gid=21(shutdown)


I'll perform more test tomorrow and take a look at the code you've put in place.

As stated in a previous reply, I'll also try to answer to: "That version
has changes to call setauthdb() based on SYSTEM rather
than registry like OpenSSH does.  Can you tell me which approach is
best?  The AIX online documentation is unclear on this."


Best regards,

Yannick Bergeron
Comment 14 Yannick Bergeron 2010-06-18 13:46:49 MDT
in aix.c, you've put the following comment: /* XXX - should NAME field be pw_gecos? */


according to http://publib.boulder.ibm.com/infocenter/aix/v6r1/topic/com.ibm.aix.basetechref/doc/basetrf2/usrinfo.htm?resultof=%22%75%73%72%69%6e%66%6f%22%20
this should be the username

so your code is ok and the comment could be removed

###
SYSTEM vs registry attribute

I agree with you that the documentation is unclear.

but according to http://publib.boulder.ibm.com/infocenter/aix/v6r1/topic/com.ibm.aix.basetechref/doc/basetrf2/setauthdb.htm?resultof=%22%73%65%74%61%75%74%68%64%62%22%20

"The New parameter must reference a value module name contained in the /usr/lib/security/methods.cfg file"

and in the header of /usr/lib/security/methods.cfg

******************************************
*
* Authentication methods:
*
* auth_method:
*       program = /any/program
*       program_64 = /any/program64
*
* auth_method corresponds to a custom authentication method specified in
* the SYSTEM attribute in /etc/security/user

So I also agree that your approach to get the attribute SYSTEM and use it in setauthdb() is the right one



I've found one thing that doesn't work. SYSTEM can be a combinaison of more than 1 domain.
example from the /etc/security/user: SYSTEM = "DCE OR DCE[UNAVAIL] AND compat"

But I haven't found any native subroutine or specification to reproduce such logic.
I know we are sometimes using this feature (ex: SYSTEM = "GSA or compat") but I'll do a few more search on it
Comment 16 Yannick Bergeron 2010-06-18 15:21:22 MDT
s/combinaison/combination/
Comment 17 Todd C. Miller 2010-06-21 17:46:28 MDT
Do you think that using getuserattr() instead of getpwnam() would resolve the problem?  I suppose the real question is whether we could avoid the setauthdb() calls by using getuserattr() for the user info.
Comment 18 Yannick Bergeron 2010-06-22 08:19:10 MDT
I think it would be doable but not the best solution, getpwnam() and getpwuid() being very standard subroutine available on all unix platforms

I've opened an Electronic Technical Response (ETR) last friday to get an answer from the AIX support.

They've replied (but don't take it as a final answer): "I agree that setauthdb() is the correct call"

They are now looking at how it should be used when there is more than one value in SYSTEM

Once I'll get a reply about this, I'll let you know
Comment 19 Yannick Bergeron 2010-06-23 10:45:23 MDT
quick update
I'm not really sure we'll find any native solution. Support is mainly suggesting to use authenticate() but sudo should be used (in our case) without password (NOPASSWD)

also, I've found that with 1.7.3b4, sudo is resolving the right uid/gid but the groups list isn't good

# what it should be
$ su - yaberge3 -c id
uid=392592(yaberge3) gid=690667(yaberge3) groups=495666(p/mdiprd01/admin),497299(p/asmprd/admin),497303(p/asmdev/admin),501115(p/pdmdev/admin),501383(p/tciprd1/admin),501387(p/tciprd0/admin),501391(p/pdmprd4/admin),502343(p/tciadmin/admin),503817(p/asmcns/admin),521701(p/tcidb/admin),521723(p/wbiadmin/admin),707338(p/mdiprd/admin),729990(p/mdicns/admin)

# in 1.7.2p7, uid, gid and groups are wrong
$ /usr/local/sudo-1.7.2p7/bin/sudo -u yaberge3 id
uid=919(yaberge3) gid=21(shutdown)

# in 1.7.3b4, only groups are wrong
$ /usr/local/sudo-1.7.3b4/bin/sudo -u yaberge3 id
uid=392592(yaberge3) gid=690667(yaberge3) groups=21(shutdown)
Comment 20 Todd C. Miller 2010-06-23 11:11:23 MDT
I think this is just a matter of setting the authdb before calling initgroups().  Can you try the following?

ftp://ftp.sudo.ws/pub/millert/sudo/sudo-1.7.3b4-aix1.tar.gz
Comment 21 Yannick Bergeron 2010-06-23 11:30:11 MDT
        cc -qlanglvl=extc89 -c -I. -I.  -g -D_ALL_SOURCE -D_LINUX_SOURCE_COMPAT -D_PATH_SUDOERS=\"/etc/sudoers\" -DSUDOERS_UID=0 -DSUDOERS_GID=0 -DSUDOERS_MODE=0440  ./aix.c
"./alloc.h", line 22.20: 1506-172 (S) Parameter type list for function easprintf contains parameters without identifiers.
"./alloc.h", line 22.29: 1506-172 (S) Parameter type list for function easprintf contains parameters without identifiers.
"./alloc.h", line 22.48: 1506-276 (S) Syntax error: possible missing '{'?
"./aix.c", line 62.25: 1506-194 (S) Incomplete type is not allowed.
make: 1254-004 The error code from the last command is 1.
Comment 22 Todd C. Miller 2010-06-23 11:39:51 MDT
Sorry about that, if you swap the order of alloc.c and compat.h in aix.c it shoudl fix the problem.
Comment 23 Yannick Bergeron 2010-06-23 11:51:50 MDT
haha, I've posted my last reply in the wrong bugzilla (one that I've
for samba)

anyway

yes much better now, and the groups are ok

$ /usr/local/sudo-1.7.2p7/bin/sudo -u yaberge3 id
uid=919(yaberge3) gid=21(shutdown)
$ /usr/local/sudo-1.7.3b4/bin/sudo -u yaberge3 id
uid=392592(yaberge3) gid=690667(yaberge3)
$ /usr/local/sudo-1.7.3b4-1/bin/sudo -u yaberge3 id
uid=392592(yaberge3) gid=690667(yaberge3)
groups=495666(p/mdiprd01/admin),497299(p/asmprd/admin),497303(p/asmdev/admin),501115(p/pdmdev/admin),501383(p/tciprd1/admin),501387(p/tciprd0/admin),501391(p/pdmprd4/admin),502343(p/tciadmin/admin),503817(p/asmcns/admin),521701(p/tcidb/admin),521723(p/wbiadmin/admin),707338(p/mdiprd/admin),729990(p/mdicns/admin)
$ su - yaberge3 -c id
uid=392592(yaberge3) gid=690667(yaberge3)
groups=495666(p/mdiprd01/admin),497299(p/asmprd/admin),497303(p/asmdev/admin),501115(p/pdmdev/admin),501383(p/tciprd1/admin),501387(p/tciprd0/admin),501391(p/pdmprd4/admin),502343(p/tciadmin/admin),503817(p/asmcns/admin),521701(p/tcidb/admin),521723(p/wbiadmin/admin),707338(p/mdiprd/admin),729990(p/mdicns/admin)
Comment 24 Yannick Bergeron 2010-06-23 14:08:37 MDT
Now that support understand that sudo doesn't necessary require authentication (like "su" does), they are suggesting the use of S_REGISTRY instead of S_AUTHSYSTEM.

Becuase the AIX online documentation is unclear on S_REGISTRY vs S_AUTHSYSTEM, I just want to confirm a thing or two with them before recompiling a 1.7.3b4-2 that would replace S_AUTHSYSTEM by S_REGISTRY
Comment 25 Yannick Bergeron 2010-06-28 08:28:33 MDT
it looks like S_REGISTRY should be used instead of S_AUTHSYSTEM
S_AUTHSYSTEM is more about authentication
S_REGISTRY is more about user information (uid, gid, groups, etc)

I currently run the latest beta you've sent me but in which I've replaced S_AUTHSYSTEM by S_REGISTRY
So far, every test case I've done are working and give me the same uid/gid/groups as if I run the "su" command to the target user
Comment 26 Todd C. Miller 2010-06-28 09:23:22 MDT
Sudo 1.7.3rc1 uses S_REGISTRY.
ftp://ftp.sudo.ws/pub/sudo/beta/sudo-1.7.3rc1.tar.gz

The 1.7.3 release will be in two days on the 30th.
Comment 27 Yannick Bergeron 2010-06-28 10:45:32 MDT
1.7.3rc1 is working fine. I'll be running it on my test env until 1.7.3 final is released.

Thanks a lot for your time and cooperation Todd.


Best regards,


Yannick Bergeron
Comment 28 Yannick Bergeron 2010-07-20 08:22:42 MDT
Todd, we've encountered another bug with 1.7.3 related to this.

We've already found a solution and are going to test it in the upcoming hours. Will send the patch as soon as possible (I've seen that you've already released 1.7.4 b1 and b2 so would be great if the final release of 1.7.4 could wait this.


Best regards,

Yannick Bergeron
Comment 29 karl 2010-07-20 12:21:39 MDT
Created attachment 279 [details]
aix.c : aix_restoreauthdb modified

After investigating the problem we found out that aix_restoredb (aix.c) doesn't restore anything since the string
provided stays empty. In fact setauthdb(authdb_t * new,authdb_t * old) sets the old parameter to the current domain
ONLY if it has been set with the setauthdb function. To summarize, sudo retreives information on the current user, then 
checks if it is in the sudoers group then changes the domain according the roots configuration in /etc/security/user.
It would look like this:

Lets say that the current user is jdoe
	
	sudo su -
	...
	
	getuserattr              //retrieving info from user jdoe
	setauthdb		 //setting domain according to jdoe's config 
				 //variable saved_registry is not initialized since its the first call to set authdb
	...
	check if jdoe is in sudoers group
   	...
	aix_restoreauthdb	 //current domain is not restored to saved_registry which is an empty string

	getuserattr		 //retrieving info from user root, 
				 //since the domain has been set to something else which doesn't contain root
				 //function returns -1 because it cannot find the user root

	setauthdb		 //never happens
	aix_restoreauthdb        //never happens

So we figured that calling setauthdb with both parameter to NULL resets the domain to the default behavior. We call
this instead of setting the current domain with the save_registry variable.

See end of second paragraph of description:
http://publib.boulder.ibm.com/infocenter/aix/v6r1/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf2/setauthdb.htm
 	
You can also take a look to the getauthdb function's return codes which gave me a pretty good idea of what was happening:
http://publib.boulder.ibm.com/infocenter/aix/v6r1/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf2/setauthdb.htm

The patch provided was tested on sudo-1.7.4b2.



Best regards,

Karl Benoit
Comment 30 Todd C. Miller 2010-07-20 13:02:42 MDT
Thanks, I've applied that to the source repo and will release a new 1.7.4 beta shortly.  It seems that the only reason this worked for openssh is that they didn't check to see if the saved registry was empty.
Comment 31 Yannick Bergeron 2010-07-20 13:52:34 MDT
compiled 1.7.4b3
tested both case we had in problem with 1.7.3, working great now

closing the bug and hoping it will stay closed :)

Thanks a lot again Todd.