[Date Prev][Date Next] [Chronological] [Thread] [Top]

(ITS#4566) incorrect descriptor handling



Full_Name: Artem Kazakov
Version: 2.3.21
OS: FreeBSD
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (130.87.161.100)


------- Forwarded Message --------
From: Christos Zoulas <christos@zoulas.com>
> To: Artem Kazakov <kazakov@gmail.com>, Tcsh-Bugs@mx.gw.com
> Subject: Re: tcsh problem
> Date: Thu, 25 May 2006 09:24:16 -0400
> 
> On May 25,  9:33am, kazakov@gmail.com (Artem Kazakov) wrote:
> -- Subject: tcsh problem
> 
> | Dear All, 
> | 
> | The story started from this pr: 
> | http://www.freebsd.org/cgi/query-pr.cgi?pr=ports/77574
> | 
> | While debugging I realized that the problem is because of the way tcsh
> | manages descriptors. 
> | So, the problem is: 
> | when you use nss_ldap, and it has persistent connections enabled. 
> | You type somthing like :
> | $ cd ~ab[tab] 
> | At this point a lookup through nss_ldap is made. At the moment
> | descriptors 0,1,2 are free. So when nss_ldap makes a call to socket() it
> | returns 1 (0 is used for logging if I get it right, and 2 is used too
> | then). And as connection stays open the descriptor is still held and
> | descriptor id = 1; 
> | So then you issue a command: 
> | $ cd ~abc[enter] 
> | at this point, tcsh makes call to doio() - as I understand this function
> | should set proper descriptors for pipe, io-redirection etc. 
> | And here is the code: 
> | 
> | doio(t, pipein, pipeout)
> |     struct command *t;
> |     int    *pipein, *pipeout;
> | {
> | .... 
> | 
> |             (void) close(0);
> |             (void) dup(OLDSTD);
> | ....  
> |            (void) close(1);
> |            (void) dup(SHOUT);
> | ....  
> |     (void) close(2);
> |     if (flags & F_STDERR) {
> |         (void) dup(1);
> |         is2atty = is1atty;
> |     }
> |     else {
> |         (void) dup(SHDIAG);
> |         is2atty = isdiagatty;
> | ....
> | 
> | So, descriptors 0,1,2 were closed and dup()ed.
> | 
> | And after that a lookup through nss_ldap is done again (we issued a
> | command cd ~abc) 
> | But it thinks that connection is still alive, and when it calls write()
> | all the data goes to terminal, instead of socket. 
> | Later, nss_ldap tries to write to syslog, but fails, because socked id=2
> | was reopened by  tcsh. And nss_ldap closes in then opens with socket(); 
> | And after, when user is not found tcsh writes error message to socket
> | id=2, and it goes to syslog.
> | 
> | The results are not we wanted to get. 
> | 
> | Current workaround exists, you just have not to use persistent
> | connections with nss_ldap. 
> | 
> | But tcsh should be fixed, I suppose. 
> | I'm not familiar with tcsh code, so can't do that. 
> 
> YP (NIS) has the same issue, but it works properly because it tests the
> file descriptor it opened before it uses it. LDAP should do the same.
> 
> christos