cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1596
Views
2
Helpful
18
Replies

CLI pipe to save to a file

sm000x
Level 1
Level 1

Hi,

I want to save a cli output to a file, however, cli does not allow me to save to a directory other than where I starts the ncs_cli.

For example, if I am in /root and start ncs_cli and I want to save cli output
to /tmp:

[root@mtnj06 ~]# ncs_cli -u admin
admin@ncs> show configuration devices device lab7smf | save /tmp/xyz100
-------------------------------------------------------------^
syntax error: access denied
[error][2023-10-05 16:11:04]

I can only save it to the directory where I start the ncs_cli:
sm000x@ncs> show configuration devices device lab7smf | save xyz100
[ok][2023-10-05 16:11:38]
sm000x@ncs> exit

I probably did something wrong.
Does anyone have same issue?

THX
sm000x

2 Accepted Solutions

Accepted Solutions

cohult
Cisco Employee
Cisco Employee

Also, make sure you have 'restricted-file-access' in ncs.conf set to 'false'. However, be mindful of the implications where CLI users will be less restricted. See the ncs.conf(5) man page for details on the restricted-file-access setting.

 

 

<cli>
    <enabled>true</enabled>
...
    <restricted-file-access>false</restricted-file-access>
...
</cli>

 

 

Note that the default ncs.conf for an NSO system installation has restricted-file-access set to true.

View solution in original post

Hi, Cohult:

Thank you so much. Somehow my system-installation has
true

I changed to false and it is working now. Now NCS is able to access to any directories as long as the login user has the permission.

This is very helpful information.

THX
sm000x

View solution in original post

18 Replies 18

WarHawk
Level 1
Level 1

Hi sm000x,

When your in /root can you use the ‘>’ operator rather than pipe?

Example:

“show configuration devices device lab7smf > /tmp/xyz100”

Hi, WarHawk:

Thank you for the response, I got the following error:
admin@ncs> show configuration devices device lab7smf > /tmp/xyz100
----------------------------------------------------------------------------^
syntax error: element does not exist
[error][2023-10-08 09:30:31]
admin@ncs>


Thank you sm000x

Hi, hniska:

Thank you for response.

(1) Are you sure your user can write in to /tmp?
sm000x: Yes, user is root.

[root@mtnjdslncs06 ncs_log]# cd /root
[root@mtnjdslncs06 ~]# touch /tmp/ppp1
[root@mtnjdslncs06 ~]# rm -rf /tmp/ppp1
[root@mtnjdslncs06 ~]# ncs_cli -u admin
User admin last logged in 2023-10-08T13:40:34.341507+00:00, to mtnjdslncs06, from 135.91.110.32 using cli-ssh
admin connected from 135.91.110.32 using ssh on mtnjdslncs06
admin@ncs> show configuration devices device lab7smf | save /tmp/ppp1
-------------------------------------------------------------^
syntax error: access denied
[error][2023-10-08 09:41:35]
admin@ncs> exit

[root@mtnjdslncs06 ~]# cd /tmp
[root@mtnjdslncs06 tmp]# ncs_cli -u admin

User admin last logged in 2023-10-08T13:41:30.894441+00:00, to mtnjdslncs06, from 135.91.110.32 using cli-ssh
admin connected from 135.91.110.32 using ssh on mtnjdslncs06
admin@ncs> show configuration devices device lab7smf | save /tmp/ppp1
[ok][2023-10-08 09:41:54]
admin@ncs>


(2) what version of NSO are you running?
sm000x: This occurs on NSO 5.7.3 and NSO 6.1
I do not have the issue with NSO 3.x

THX
sm000x

hniska
Cisco Employee
Cisco Employee

First ">" isn't an operator in the nso cli so no need to try that. 

Are you sure your user can write in to /tmp? 

But I also think that the error message looks strange (what version of NSO are you running?), this is how it usually looks when you dont have the right user rights

admin@ncs> show configuration devices global-settings | save /var/log/xyz100
Error: failed to open file: Missing permission for the file or one of its parents. File: xyz100
Aborted: failed to write to file

And even if the directory doesnt exist we should get a similar error message

admin@ncs> show configuration devices global-settings | save /nonexisting/xyz100
Error: failed to open file: Missing permission for the file or one of its parents. File: xyz100
Aborted: failed to write to file

hniska
Cisco Employee
Cisco Employee

Could be the new Ubuntu 20.04 behaviour with fs.protected_regular kernel parameter. You can try disabling it like this

sudo sysctl fs.protected_regular=0

Just a guess and you should probably google it a bit before taking my word for it :). 

Hi, hniska:

Thank you for the suggestion. I will give it a try.

THX
sm000x

Hi, hniska:

I set fs.protected_regular=0
Unfortunately, it does not help:
(venv) -bash-5.1# sysctl fs.protected_regular=0
fs.protected_regular = 0
(venv) -bash-5.1# ncs_cli -u admin

User admin last logged in 2023-10-08T18:42:13.419491+00:00, to mtznjv1pinc18, from 135.91.110.32 using cli-ssh
admin connected from 135.91.110.32 using ssh on mtznjv1pinc18
admin@ncs> show configuration nacm | save /tmp/ppp
-------------------------------------------^
syntax error: access denied
[error][2023-10-08 18:44:22]
admin@ncs>

THX
sm000x

hniska
Cisco Employee
Cisco Employee

My guess is still that its something around that feature, can you write in other folders that root owns, something that you created in the home folder for example? 

namei: allow restricted O_CREAT of FIFOs and regular files

Disallows open of FIFOs or regular files not owned by the user in world writable sticky directories, unless the owner is the same as that of the directory or the file is opened without the O_CREAT flag. The purpose is to make data spoofing attacks harder....

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/sysctl/fs.txt?id=30aba6656f61ed44cba445a3c0d38b296fa9e8f5

Hi, hniska:

Thank you for the suggestion.
I cannot save to any folder except where I start the ncs_cli.

Maybe there is something I missed in ncs.conf?
I will test allow restricted O_CREAT of FIFOs and regular files.


Thx
sm000x

It looks like something about your environment. To investigate this further I would use strace to run ncs_cli and get a log of all the system calls it is making. The first thing I would then look for is the open system call where ncs_cli opens the file. Or any system other call where the file name occurs as a parameter, just by using grep to search for the file name in the strace output.

That would make it clear which system call is failing and what error code it produces. If it is simply a permission issue you will see the open call returning EACCES code 13, but if you see other system calls, that might give a clue to what it is in the environment that does not allow this.

 

execve("/opt/ncs/current/bin/ncs_cli", ["ncs_cli", "-u", "admin"], 0x7ffd060d7930 /* 24 vars */) = 0
brk(NULL) = 0x5566b0844000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbdece77000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/opt/ncs/current/lib/tls/x86_64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/opt/ncs/current/lib/tls/x86_64", 0x7ffe1b8e3e20) = -1 ENOENT (No such file or directory)
open("/opt/ncs/current/lib/tls/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/opt/ncs/current/lib/tls", 0x7ffe1b8e3e20) = -1 ENOENT (No such file or directory)
open("/opt/ncs/current/lib/x86_64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/opt/ncs/current/lib/x86_64", 0x7ffe1b8e3e20) = -1 ENOENT (No such file or directory)
open("/opt/ncs/current/lib/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/opt/ncs/current/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=38003, ...}) = 0
mmap(NULL, 38003, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fbdece6d000
close(3) = 0
open("/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200m\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=142144, ...}) = 0
mmap(NULL, 2208904, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fbdeca3b000
mprotect(0x7fbdeca52000, 2093056, PROT_NONE) = 0
mmap(0x7fbdecc51000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16000) = 0x7fbdecc51000
mmap(0x7fbdecc53000, 13448, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fbdecc53000
close(3) = 0
open("/opt/ncs/current/lib/libdl.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\16\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=19248, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbdece6c000
mmap(NULL, 2109744, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fbdec837000
mprotect(0x7fbdec839000, 2097152, PROT_NONE) = 0
mmap(0x7fbdeca39000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7fbdeca39000
close(3) = 0
open("/opt/ncs/current/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`&\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2156344, ...}) = 0
mmap(NULL, 3985920, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fbdec469000
mprotect(0x7fbdec62d000, 2093056, PROT_NONE) = 0
mmap(0x7fbdec82c000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c3000) = 0x7fbdec82c000
mmap(0x7fbdec832000, 16896, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fbdec832000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbdece6b000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbdece69000
arch_prctl(ARCH_SET_FS, 0x7fbdece69740) = 0
mprotect(0x7fbdec82c000, 16384, PROT_READ) = 0
mprotect(0x7fbdeca39000, 4096, PROT_READ) = 0
mprotect(0x7fbdecc51000, 4096, PROT_READ) = 0
mprotect(0x7fbdece78000, 4096, PROT_READ) = 0
munmap(0x7fbdece6d000, 38003) = 0
set_tid_address(0x7fbdece69a10) = 35255
set_robust_list(0x7fbdece69a20, 24) = 0
rt_sigaction(SIGRTMIN, {sa_handler=0x7fbdeca41860, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7fbdeca4a630}, NULL, = 0
rt_sigaction(SIGRT_1, {sa_handler=0x7fbdeca418f0, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0x7fbdeca4a630}, NULL, = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, = 0
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
brk(NULL) = 0x5566b0844000
brk(0x5566b0865000) = 0x5566b0865000
brk(NULL) = 0x5566b0865000
getcwd("/opt/ncs/var/opt/ncs", 1024) = 21
geteuid() = 0
getegid() = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
readlink("/proc/self/fd/0", "/dev/pts/2", 31) = 10
stat("/dev/pts/2", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(4569), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
write(3, "\4", 1) = 1
read(3, "\0", 1) = 1
write(3, "1.2", 3) = 3
write(3, ";", 1) = 1
getgroups(0, NULL) = 3
getgroups(3, [0, 1001, 1002]) = 3
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 4
connect(4, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
close(4) = 0
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 4
connect(4, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
close(4) = 0
open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=1746, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbdece76000
read(4, "#\n# /etc/nsswitch.conf\n#\n# An ex"..., 4096) = 1746
read(4, "", 4096) = 0
close(4) = 0
munmap(0x7fbdece76000, 4096) = 0
open("/opt/ncs/current/lib/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=38003, ...}) = 0
mmap(NULL, 38003, PROT_READ, MAP_PRIVATE, 4, 0) = 0x7fbdece6d000
close(4) = 0
open("/lib64/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 4
read(4, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260!\0\0\0\0\0\0"..., 832) = 832
fstat(4, {st_mode=S_IFREG|0755, st_size=61560, ...}) = 0
mmap(NULL, 2173048, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4, 0) = 0x7fbdec256000
mprotect(0x7fbdec262000, 2093056, PROT_NONE) = 0
mmap(0x7fbdec461000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0xb000) = 0x7fbdec461000
mmap(0x7fbdec463000, 22648, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fbdec463000
close(4) = 0
mprotect(0x7fbdec461000, 4096, PROT_READ) = 0
munmap(0x7fbdece6d000, 38003) = 0
open("/etc/group", O_RDONLY|O_CLOEXEC) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=873, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbdece76000
read(4, "root:x:0:\nbin:x:1:\ndaemon:x:2:\ns"..., 4096) = 873
close(4) = 0
munmap(0x7fbdece76000, 4096) = 0
open("/etc/group", O_RDONLY|O_CLOEXEC) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=873, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbdece76000
read(4, "root:x:0:\nbin:x:1:\ndaemon:x:2:\ns"..., 4096) = 873
close(4) = 0
munmap(0x7fbdece76000, 4096) = 0
open("/etc/group", O_RDONLY|O_CLOEXEC) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=873, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbdece76000
read(4, "root:x:0:\nbin:x:1:\ndaemon:x:2:\ns"..., 4096) = 873
close(4) = 0
munmap(0x7fbdece76000, 4096) = 0
open("/etc/group", O_RDONLY|O_CLOEXEC) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=873, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbdece76000
read(4, "root:x:0:\nbin:x:1:\ndaemon:x:2:\ns"..., 4096) = 873
close(4) = 0
munmap(0x7fbdece76000, 4096) = 0
open("/etc/group", O_RDONLY|O_CLOEXEC) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=873, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbdece76000
read(4, "root:x:0:\nbin:x:1:\ndaemon:x:2:\ns"..., 4096) = 873
close(4) = 0
munmap(0x7fbdece76000, 4096) = 0
open("/etc/group", O_RDONLY|O_CLOEXEC) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=873, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbdece76000
read(4, "root:x:0:\nbin:x:1:\ndaemon:x:2:\ns"..., 4096) = 873
close(4) = 0
munmap(0x7fbdece76000, 4096) = 0
getgroups(0, NULL) = 3
getgroups(3, [0, 1001, 1002]) = 3
write(3, "admin", 5) = 5
write(3, ";", 1) = 1
write(3, "127.0.0.1", 9) = 9
write(3, ";", 1) = 1
write(3, "console", 7) = 7
write(3, ";", 1) = 1
write(3, "root,ncsadmin,ncsoper", 21) = 21
write(3, ";", 1) = 1
write(3, "HOST=", 5) = 5
write(3, ";", 1) = 1
write(3, "/dev/pts/2", 10) = 10
write(3, ";", 1) = 1
write(3, "/opt/ncs/var/opt/ncs", 20) = 20
write(3, ";", 1) = 1
write(3, "xterm", 5) = 5
write(3, ";", 1) = 1
write(3, ";", 1) = 1
write(3, "unset", 5) = 5
write(3, ";", 1) = 1
write(3, "\0\0\0\0\0\0\0\0", = 8
write(3, "\0\0\0\0\0\0\0\0", = 8
write(3, "\0\0\0\0\0\0\3", 7) = 7
write(3, "\0\0\0\0\0\0\0\0", = 8
write(3, "\0\0\0\0\3\351", 6) = 6
write(3, "\0\0\0\0\3\352", 6) = 6
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, SNDCTL_TMR_CONTINUE or TCSETSF, {B38400 opost -isig -icanon -echo ...}) = 0
rt_sigaction(SIGWINCH, {sa_handler=0x5566aef056d0, sa_mask=[WINCH], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7fbdec49f450}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, = 0
ioctl(0, TIOCGWINSZ, {ws_row=24, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0
write(3, "\0\0\0\0\0\0P", 7) = 7
write(3, "\0\0\0\0\0\0\30", 7) = 7
write(3, "\0\0\0\0\0\0\1", 7) = 7
write(3, "\0\0\0\0\0\0\0\0", = 8
write(3, "\0\0\0\0\0\0\0\0", = 8
write(3, "\0\0\0\0\0\0\1", 7) = 7
fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
fcntl(1, F_GETFL) = 0x8002 (flags O_RDWR|O_LARGEFILE)
fcntl(1, F_SETFL, O_RDWR|O_NONBLOCK|O_LARGEFILE) = 0
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "\nUser admin last logged in 2023-"..., 1024) = 188
write(1, "\nUser admin last logged in 2023-"..., 188) = 188
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLIN}])
read(0, "show configuration nacm | save", 1024) = 30
write(3, "show configuration nacm | save", 30) = 30
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "show", 1024) = 4
write(1, "show", 4) = 4
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, " configuration", 1024) = 14
write(1, " configuration", 14) = 14
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, " nacm", 1024) = 5
write(1, " nacm", 5) = 5
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, " |", 1024) = 2
write(1, " |", 2) = 2
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, " ", 1024) = 1
write(1, " ", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "save", 1024) = 4
write(1, "save", 4) = 4
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLIN}])
read(0, " ", 1024) = 1
write(3, " ", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, " ", 1024) = 1
write(1, " ", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLIN}])
read(0, "/", 1024) = 1
write(3, "/", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "/", 1024) = 1
write(1, "/", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLIN}])
read(0, "t", 1024) = 1
write(3, "t", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "t", 1024) = 1
write(1, "t", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLIN}])
read(0, "m", 1024) = 1
write(3, "m", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "m", 1024) = 1
write(1, "m", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLIN}])
read(0, "p", 1024) = 1
write(3, "p", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "p", 1024) = 1
write(1, "p", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLIN}])
read(0, "/", 1024) = 1
write(3, "/", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "/", 1024) = 1
write(1, "/", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLIN}])
read(0, "a", 1024) = 1
write(3, "a", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "a", 1024) = 1
write(1, "a", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLIN}])
read(0, "a", 1024) = 1
write(3, "a", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "a", 1024) = 1
write(1, "a", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLIN}])
read(0, "a", 1024) = 1
write(3, "a", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "a", 1024) = 1
write(1, "a", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLIN}])
read(0, "\r", 1024) = 1
write(3, "\r", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "\n", 1024) = 1
write(1, "\n", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "--------------------------------"..., 1024) = 113
write(1, "--------------------------------"..., 113) = 113
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLIN}])
read(0, "e", 1024) = 1
write(3, "e", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "e", 1024) = 1
write(1, "e", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLIN}])
read(0, "x", 1024) = 1
write(3, "x", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "x", 1024) = 1
write(1, "x", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLIN}])
read(0, "i", 1024) = 1
write(3, "i", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "i", 1024) = 1
write(1, "i", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLIN}])
read(0, "t", 1024) = 1
write(3, "t", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "t", 1024) = 1
write(1, "t", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLIN}])
read(0, "\r", 1024) = 1
write(3, "\r", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "\n", 1024) = 1
write(1, "\n", 1) = 1
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "\0\376", 1024) = 2
poll([{fd=0, events=POLLIN}, {fd=3, events=POLLIN}], 2, -1) = 1 ([{fd=3, revents=POLLIN}])
read(3, "", 1024) = 0
ioctl(1, SNDCTL_TMR_CONTINUE or TCSETSF, {B38400 opost isig icanon echo ...}) = 0
fcntl(3, F_SETFL, O_RDWR) = 0
fcntl(1, F_SETFL, O_RDWR|O_LARGEFILE) = 0
exit_group(0) = ?
+++ exited with 0 +++

alex-filippov
Level 1
Level 1

Same behaviour for me for NSO 5.7.5.1 system install on RHEL 7.9:
"syntax error: access denied" when saving ouside of the current folder.

Local install on Fedora works ok, can save to any folder.

Also, it's the NSO daemon (ncs.smp) who opens and writes the file, not ncs_cli process.
Hence, the user which runs NSO daemon is relevant here and must have the appropriate permissions, otherwise "save" attempt gives the error "Missing permission".
NSO daemon does know though the directory where ncs_cli was started from, and apparently in system install (?) decides to throw "syntax error: access denied" when given another directory in "save PATH", even if permissions are ok.

Undocumented security feature?
Not a big problem though, once we understand the behaviour: just `cd` where needed before `ncs_cli`.

Thank you alex-filippov for the explanation. Hopefully NSO can fix it in the future release.

THX
sm000x

cohult
Cisco Employee
Cisco Employee

@sm000x , this is not an NSO issue if NSO is started from a non-root user where you use a local NSO user (admin) when logging in that does not have access rights to the folder you are having NSO write to.
I suggest you use the ncs_load command (which uses MAAPI) to save data. E.g.
ncs_load -Fc -p /devices/device{lab7smf} > /tmp/xyz100