Discussion:
[rancid] rancid 2.3.6: clogin with multiple devices fails... ($autologin not defined)
Jon Peatfield
2011-06-13 21:58:33 UTC
Permalink
I originally thought that this might be a config error on my part but
currently for me with rancid 2.3.6 I can happily run:

clogin -c 'some-command' router1

or

clogin -c 'some-command' router2

but not:

clogin -c 'some-command' router1 router2

(or router1 router1 for that matter)

When I try I get an error from the tcl about autoenable not being a
variable. Here is an example failure:

$ clogin -c 'who' bl23-12.private bl23-13.private
bl23-12.private
spawn telnet bl23-12.private
Trying 10.16.0.124...
Connected to bl23-12.private.
Escape character is '^]'.

User Access Verification

Username: cisco
Password:
bl23-12>enable
Password:
bl23-12#
bl23-12#terminal length 0
bl23-12#who
Line User Host(s) Idle Location
* 1 vty 0 cisco idle 00:00:00 <SNIP>

Interface User Mode Idle Peer
Address

bl23-12#exit
Connection closed by foreign host.
bl23-13.private
can't read "autoenable": no such variable
while executing
"if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2
} {
send_user -- "\nError: no enable password for $router in
$password_file...."
("foreach" body line 28)
invoked from within
"foreach router [lrange $argv $i end] {
set router [string tolower $router]
# attempt at platform switching.
set platform ""
send_user ..."
(file "/usr/bin/clogin" line 743)

it always fails on the second host, so it isn't just that the config for
the second router is wrong. Adding an explicit 'add autoenable ... {0}'
does not seem to help...

On our HP procurve devices we do use autoenable (defined in the .cloginrc)
and for those hlogin works as expected... In fact apart from some errors
from the 'no-page' command I can use hlogin -c '...' against multiple
cisco devices without getting similar errors (at least for trivial
commands).

Looking at the (unpatched I hope) clogin.in file from the 2.3.6 tar I see
that at about line 770 is the offending code:

...
if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } {
send_user -- "\nError: no enable password for $router in $password_file.\n"
continue
}
...

but I can't see anything which ever sets autoenable in this file... What
really puzzled me is that the error only happens on the second router...

A bit of debugging shows that on the first loop $enable is 0 so it never
tests beyond it - even though it will be about to use enable, and when it
finds a > prompt it sets enable to 1 so the next time round the test check
$do_enapasswd (true) and $autoenable (no defined) and we get an error.

So a little further up (about line 742 - the top of the loop) we have:

...
set enable 0
foreach router [lrange $argv $i end] {
set router [string tolower $router]
...

Changing that to:

...
foreach router [lrange $argv $i end] {
set enable 0
set router [string tolower $router]
...

so that enable is initially set to 0 for each router, appears to cure the
problem for me, but it may have unexpected side effects and surely
$autoenable isn't the right thing to be testing is it?

Maybe this test is left over from an earlier version of the code. I note
that in hlogin.in the loop over the routers is quite different and does
set autologin for each device in the loop.

At the moment I can just use a shell script to loop over each device and
so avoid listing multiple hosts on the clogin command, but I was very
surprised by it not doing what I expected - since I'd used an almost
identical command with hlogin a few days earlier.
--
/--------------------------------------------------------------------\
| "Computers are different from telephones. Computers do not ring." |
| -- A. Tanenbaum, "Computer Networks", p. 32 |
---------------------------------------------------------------------|
| Jon Peatfield, _Computer_ Officer, DAMTP, University of Cambridge |
| Mail: ***@damtp.cam.ac.uk Web: http://www.damtp.cam.ac.uk/ |
\--------------------------------------------------------------------/
Jon Peatfield
2011-06-23 22:31:16 UTC
Permalink
Post by Jon Peatfield
I originally thought that this might be a config error on my part but
clogin -c 'some-command' router1
or
clogin -c 'some-command' router2
clogin -c 'some-command' router1 router2
<snip>
Post by Jon Peatfield
At the moment I can just use a shell script to loop over each device and so
avoid listing multiple hosts on the clogin command, but I was very surprised
by it not doing what I expected - since I'd used an almost identical command
with hlogin a few days earlier.
<deathly quiet>

So is this something specific to my copy of rancid, or is this just a well
known thing to be avoided?

-- Jon
Lee
2011-06-24 00:09:48 UTC
Permalink
Hi,
Post by Jon Peatfield
Post by Jon Peatfield
I originally thought that this might be a config error on my part but
clogin -c 'some-command' router1
or
clogin -c 'some-command' router2
clogin -c 'some-command' router1 router2
<snip>
Post by Jon Peatfield
At the moment I can just use a shell script to loop over each device and so
avoid listing multiple hosts on the clogin command, but I was very surprised
by it not doing what I expected - since I'd used an almost identical command
with hlogin a few days earlier.
<deathly quiet>
So is this something specific to my copy of rancid, or is this just a well
known thing to be avoided?
I'd never tried it before, so I stayed quiet :) But it's easy enough
to test, so
clogin -c "sh ip eigrp int" router1 router2 router3 ... router20
worked for me using rancid 2.3.6

Lee
Jon Peatfield
2011-07-06 14:55:44 UTC
Permalink
Post by Lee
Hi,
<snip>
Post by Lee
Post by Jon Peatfield
<deathly quiet>
So is this something specific to my copy of rancid, or is this just a well
known thing to be avoided?
I'd never tried it before, so I stayed quiet :) But it's easy enough
to test, so
clogin -c "sh ip eigrp int" router1 router2 router3 ... router20
worked for me using rancid 2.3.6
As discussed off the list, it works ok if clogin isn't set to use enable
ie if you have autoenable or noenable set.

The bug seems is triggered if the $enable variable gets set, then the next
time round the loop it calls code which references a variable which isn't
defined (anywhere in the code).

I can see a number of possible fixes to the current clogin code but would
prefer an expert to take a look at it...

-- Jon
Lee
2011-07-14 00:10:51 UTC
Permalink
Post by Jon Peatfield
Post by Lee
Hi,
<snip>
Post by Lee
Post by Jon Peatfield
<deathly quiet>
So is this something specific to my copy of rancid, or is this just a well
known thing to be avoided?
I'd never tried it before, so I stayed quiet :) But it's easy enough
to test, so
clogin -c "sh ip eigrp int" router1 router2 router3 ... router20
worked for me using rancid 2.3.6
As discussed off the list, it works ok if clogin isn't set to use enable
ie if you have autoenable or noenable set.
The bug seems is triggered if the $enable variable gets set, then the next
time round the loop it calls code which references a variable which isn't
defined (anywhere in the code).
I can see a number of possible fixes to the current clogin code but would
prefer an expert to take a look at it...
... crickets ...

OK, how 'bout a proposed fix? Starting at my line 756 in clogin it's:
set enable 0
foreach router [lrange $argv $i end] {
set router [string tolower $router]
# attempt at platform switching.

Fix is to move the "set enable 0" line after the "foreach router [..." line.

Lee
Jon Peatfield
2011-07-14 00:57:21 UTC
Permalink
Post by Lee
Post by Jon Peatfield
I can see a number of possible fixes to the current clogin code but would
prefer an expert to take a look at it...
... crickets ...
set enable 0
foreach router [lrange $argv $i end] {
set router [string tolower $router]
# attempt at platform switching.
Fix is to move the "set enable 0" line after the "foreach router [..." line.
Which does seem to fix it, or at least hide the underlying problems...

My worry is that the code is testing $enable in the loop before it can be
set other than to 0, so either the testing of $enable code is wrong, or it
really is intended to be the value of $enable from the *previous* time
round the loop, in which case the fix may break something subtle...

Then there is the use of $autoenable itself, which I assume was left when
the variable was renamed, but it isn't obvious (to me) if that should be
$avautoenable or $ae since I don't understand what the test is meant to be
doing...

So we have (in the unfixed 2.3.6):

...
set enable 0
foreach router [lrange $argv $i end] {
...
# look for noenable option in .cloginrc
if { [find noenable $router] == "1" } {
set enable 0
}
...
if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } {
send_user -- "\nError: no enable password for $router in $password_file.\n"
continue
}
...
<things which set enable and tests of it>
...
}

so maybe that test of $enable just needs to be moved after the places
where enable is set...

I clearly don't understand the code.

-- Jon
P C
2011-09-06 23:16:02 UTC
Permalink
Has any determined the best solution for this? I just upgraded from
version 2.3.1_3 to 2.3.6 and now I'm having this problem too.

I used to do clogin -c "show inventory" `cat all_routers.txt` and it
would return said command for the routers listed in all_routers.txt,
with one router entry per line.

Now, the first routers runs fine, but each subsequent one gives this:

can't read "autoenable": no such variable
while executing
"if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } {
send_user -- "\nError: no enable password for $router in
$password_file...."
("foreach" body line 28)
invoked from within
"foreach router [lrange $argv $i end] {
set router [string tolower $router]
# attempt at platform switching.
set platform ""
send_user ..."
(file "/usr/local/rancid/bin/clogin" line 743)


On Wed, Jul 13, 2011 at 6:57 PM, Jon Peatfield
Post by Jon Peatfield
Post by Jon Peatfield
I can see a number of possible fixes to the current clogin code but would
prefer an expert to take a look at it...
 ... crickets ...
set enable 0
foreach router [lrange $argv $i end] {
  set router [string tolower $router]
  # attempt at platform switching.
Fix is to move the "set enable 0" line after the "foreach router [..." line.
Which does seem to fix it, or at least hide the underlying problems...
My worry is that the code is testing $enable in the loop before it can be
set other than to 0, so either the testing of $enable code is wrong, or it
really is intended to be the value of $enable from the *previous* time round
the loop, in which case the fix may break something subtle...
Then there is the use of $autoenable itself, which I assume was left when
the variable was renamed, but it isn't obvious (to me) if that should be
$avautoenable or $ae since I don't understand what the test is meant to be
doing...
...
set enable 0
foreach router [lrange $argv $i end] {
...
   # look for noenable option in .cloginrc
   if { [find noenable $router] == "1" } {
       set enable 0
   }
...
     if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] <
2 } {
       send_user -- "\nError: no enable password for $router in
$password_file.\n"
       continue
     }
...
<things which set enable and tests of it>
...
}
so maybe that test of $enable just needs to be moved after the places where
enable is set...
I clearly don't understand the code.
 -- Jon
_______________________________________________
Rancid-discuss mailing list
http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss
Jon Peatfield
2011-09-08 01:29:36 UTC
Permalink
Post by P C
Has any determined the best solution for this? I just upgraded from
version 2.3.1_3 to 2.3.6 and now I'm having this problem too.
I used to do clogin -c "show inventory" `cat all_routers.txt` and it
would return said command for the routers listed in all_routers.txt,
with one router entry per line.
<snip>

I'm currently just looping over the devices calling clogin for each
device:

for i in $(cat all_routers.txt); do clogin -c "...." $i; done

etc. That works for me for now.

-- Jon
Lee
2011-09-10 02:01:20 UTC
Permalink
Post by P C
Has any determined the best solution for this?
I don't know if it's "best" but it's probably "easiest"

OK, how 'bout a proposed fix? Starting at my line 756 in clogin it's:
set enable 0
foreach router [lrange $argv $i end] {
set router [string tolower $router]
# attempt at platform switching.

Fix is to move the "set enable 0" line after the "foreach router [..." line.

Can you try it & report back if it works or not for you?

Regards,
Lee
Post by P C
I just upgraded from
version 2.3.1_3 to 2.3.6 and now I'm having this problem too.
I used to do clogin -c "show inventory" `cat all_routers.txt` and it
would return said command for the routers listed in all_routers.txt,
with one router entry per line.
can't read "autoenable": no such variable
while executing
"if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } {
send_user -- "\nError: no enable password for $router in
$password_file...."
("foreach" body line 28)
invoked from within
"foreach router [lrange $argv $i end] {
set router [string tolower $router]
# attempt at platform switching.
set platform ""
send_user ..."
(file "/usr/local/rancid/bin/clogin" line 743)
On Wed, Jul 13, 2011 at 6:57 PM, Jon Peatfield
Post by Jon Peatfield
Post by Lee
Post by Jon Peatfield
I can see a number of possible fixes to the current clogin code but would
prefer an expert to take a look at it...
... crickets ...
set enable 0
foreach router [lrange $argv $i end] {
set router [string tolower $router]
# attempt at platform switching.
Fix is to move the "set enable 0" line after the "foreach router [..." line.
Which does seem to fix it, or at least hide the underlying problems...
My worry is that the code is testing $enable in the loop before it can be
set other than to 0, so either the testing of $enable code is wrong, or it
really is intended to be the value of $enable from the *previous* time round
the loop, in which case the fix may break something subtle...
Then there is the use of $autoenable itself, which I assume was left when
the variable was renamed, but it isn't obvious (to me) if that should be
$avautoenable or $ae since I don't understand what the test is meant to be
doing...
...
set enable 0
foreach router [lrange $argv $i end] {
...
# look for noenable option in .cloginrc
if { [find noenable $router] == "1" } {
set enable 0
}
...
if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd]
<
2 } {
send_user -- "\nError: no enable password for $router in $password_file.\n"
continue
}
...
<things which set enable and tests of it>
...
}
so maybe that test of $enable just needs to be moved after the places where
enable is set...
I clearly don't understand the code.
-- Jon
_______________________________________________
Rancid-discuss mailing list
http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss
Loading...