/* Samba REXX Function Library for RPC calls */
/*
Copyright (C) 2007-2017 Herwig Bauernfeind for bww bitwise works GmbH.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
/* Currently implemented functions: */
/* _rpcenumdomgroups(server,username,password) */
/* _rpcenumdomusers(server,username,password) */
/* _rpcenumprinters(server,username,password) */
/* _rpcnetshareenum(server,username,password) */
/* _rpcnetsharegetinfo(server,username,password,share) */
/* _rpcquerygroupmem(server,username,password,grouprid) */
/* _rpcqueryuser(server,username,password,userrid) */
/* _rpcsrvinfo(server,username,password) */
/*:VRX _rpcenumdomgroups
*/
_rpcenumdomgroups: procedure expose rpc. samba. options. debuglevel
IF options.!debug == 1 THEN SAY time()" _rpcenumdomgroups() started"
server = arg(1)
username = arg(2)
password = arg(3)
call VRSet VRWindow(), 'Pointer', 'Wait'
say ' 'samba.!rpcclientexe' 'server' --user='username'%'password' --command="enumdomgroups" 'debuglevel' '
address cmd samba.!rpcclientexe' 'server' --user='username'%'password' --command="enumdomgroups" 'debuglevel' >'samba.!msg
call VRSet VRWindow(), 'Pointer', ''
rpc.enumdomgroups. = ""
Failure = 0
count = 0
SIGNAL ON SYNTAX NAME RPCERROR
do until lines(samba.!msg) = 0
rpcline = linein(samba.!msg)
if pos("creating default valid table",rpcline) <> 0 then iterate
if pos("LOGON_FAILURE", rpcline) > 0 then do
Failure = 1
leave
end
parse var rpcline 'group:['tuser'] rid:['trid']'
token = translate(strip(strip(translate(token),'L','09'x)),'_',' ')
tvalue= strip(strip(tvalue,'L','09'x))
count = count + 1
dyn = 'rpc.enumdomgroups.'count'.GROUP = "'Tuser'"'
say " "dyn
interpret dyn
dyn = 'rpc.enumdomgroups.'count'.RID = "'Trid'"'
say " "dyn
interpret dyn
end
SIGNAL OFF SYNTAX
ok = stream(samba.!msg,'c','close')
ok = SysFileDelete(samba.!msg)
rpc.enumdomgroups.0 = count
if Failure = 0 then do
retval = 1
rpc.enumdomgroups.LOGONSTATUS="OK"
end
else do
retval = 0
rpc.enumdomgroups.LOGONSTATUS=substr(rpcline,pos("NT_STATUS",rpcline),)
end
IF options.!debug == 1 THEN SAY time()" _rpcenumdomgroups() done, "retval" "rpc.enumdomgroups.LOGONSTATUS
return retval
/*:VRX _rpcenumdomusers
*/
_rpcenumdomusers: procedure expose rpc. samba. options. debuglevel
IF options.!debug == 1 THEN SAY time()" _rpcenumdomusers() started"
server = arg(1)
username = arg(2)
password = arg(3)
call VRSet VRWindow(), 'Pointer', 'Wait'
say ' 'samba.!rpcclientexe' 'server' --user='username'%'password' --command="enumdomusers" 'debuglevel' '
address cmd samba.!rpcclientexe' 'server' --user='username'%'password' --command="enumdomusers" 'debuglevel' >'samba.!msg
call VRSet VRWindow(), 'Pointer', ''
rpc.enumdomusers. = ""
Failure = 0
count = 0
SIGNAL ON SYNTAX NAME RPCERROR
do until lines(samba.!msg) = 0
rpcline = linein(samba.!msg)
if pos("creating default valid table",rpcline) <> 0 then iterate
if pos("LOGON_FAILURE", rpcline) > 0 then do
Failure = 1
leave
end
parse var rpcline 'user:['tuser'] rid:['trid']'
token = translate(strip(strip(translate(token),'L','09'x)),'_',' ')
tvalue= strip(strip(tvalue,'L','09'x))
count = count + 1
dyn = 'rpc.enumdomusers.'count'.USER = "'Tuser'"'
say " "dyn
interpret dyn
dyn = 'rpc.enumdomusers.'count'.RID = "'Trid'"'
say " "dyn
interpret dyn
end
SIGNAL OFF SYNTAX
ok = stream(samba.!msg,'c','close')
ok = SysFileDelete(samba.!msg)
rpc.enumdomusers.0 = count
if Failure = 0 then do
retval = 1
rpc.enumdomusers.LOGONSTATUS="OK"
end
else do
retval = 0
rpc.enumdomusers.LOGONSTATUS=substr(rpcline,pos("NT_STATUS",rpcline),)
end
IF options.!debug == 1 THEN SAY time()" _rpcenumdomusers() done, "retval" "rpc.enumdomusers.LOGONSTATUS
return retval
/*:VRX _rpcenumprinters
*/
_rpcenumprinters: procedure expose rpc. samba. options. debuglevel
IF options.!debug == 1 THEN SAY time()" _rpcenumprinters() started"
server = arg(1)
username = arg(2)
password = arg(3)
usercred = '--user='username'%'password
call VRSet VRWindow(), 'Pointer', 'Wait'
say ' 'samba.!rpcclientexe' 'server' 'usercred' --command="enumprinters" 'debuglevel' '
address cmd samba.!rpcclientexe' 'server' 'usercred' --command="enumprinters" 'debuglevel' >'samba.!msg
call VRSet VRWindow(), 'Pointer', ''
rpc.enumprinters. = ""
Failure = 0
count = 0
SIGNAL ON SYNTAX NAME RPCERROR
do until lines(samba.!msg) = 0
rpcline = linein(samba.!msg)
if pos("creating default valid table",rpcline) <> 0 then iterate
if pos("LOGON_FAILURE", rpcline) > 0 then do
Failure = 1
leave
end
parse var rpcline token ':[' tvalue']' .
token = translate(strip(strip(translate(token),'L','09'x)),'_',' ')
if Token = "FLAGS" then count = count + 1
tvalue= strip(strip(tvalue,'L','09'x))
if pos('[',Token) = 0 & pos('TABLE',Token) = 0 & Token <> "" then do
dyn = 'rpc.enumprinters.'count'.'Token' = "'Tvalue'"'
say " "dyn
interpret dyn
end
end
SIGNAL OFF SYNTAX
ok = stream(samba.!msg,'c','close')
ok = SysFileDelete(samba.!msg)
rpc.enumprinters.0 = count
if Failure = 0 then do
retval = 1
rpc.enumprinters.LOGONSTATUS="OK"
end
else do
retval = 0
rpc.enumprinters.LOGONSTATUS=substr(rpcline,pos("NT_STATUS",rpcline),)
end
IF options.!debug == 1 THEN SAY time()" _rpcenumprinters() done, "retval" "rpc.enumprinters.LOGONSTATUS
return retval
/*:VRX _rpcnetshareenum
*/
_rpcnetshareenum: procedure expose rpc. samba. options. debuglevel
IF options.!debug == 1 THEN SAY time()" _rpcnetshareenum() started"
server = arg(1)
username = arg(2)
password = arg(3)
call VRSet VRWindow(), 'Pointer', 'Wait'
say ' 'samba.!rpcclientexe' 'server' --user='username'%'password' --command="netshareenum" 'debuglevel' '
address cmd samba.!rpcclientexe' 'server' --user='username'%'password' --command="netshareenum" 'debuglevel' >'samba.!msg
call VRSet VRWindow(), 'Pointer', ''
rpc.netshareenum. = ""
Failure = 0
count = 0
SIGNAL ON SYNTAX NAME RPCERROR
do until lines(samba.!msg) = 0
rpcline = linein(samba.!msg)
if pos("creating default valid table",rpcline) <> 0 then iterate
if pos("LOGON_FAILURE", rpcline) > 0 then do
Failure = 1
leave
end
parse var rpcline token ':' tvalue
token = translate(strip(strip(translate(token),'L','09'x)),'_',' ')
if Token = "NETNAME" then count = count + 1
tvalue= strip(strip(tvalue,'L','09'x))
if pos('[',Token) = 0 & pos('TABLE',Token) = 0 & Token <> "" then do
dyn = 'rpc.netshareenum.'count'.'Token' = "'Tvalue'"'
say " "dyn
interpret dyn
end
end
SIGNAL OFF SYNTAX
ok = stream(samba.!msg,'c','close')
ok = SysFileDelete(samba.!msg)
rpc.netshareenum.0 = count
if Failure = 0 then do
retval = 1
rpc.netshareenum.LOGONSTATUS="OK"
end
else do
retval = 0
rpc.netshareenum.LOGONSTATUS=substr(rpcline,pos("NT_STATUS",rpcline),)
end
IF options.!debug == 1 THEN SAY time()" _rpcnetshareenum() done, "retval" "rpc.netshareenum.LOGONSTATUS
return retval
/*:VRX _rpcnetsharegetinfo
*/
_rpcnetsharegetinfo: procedure expose rpc. samba. options. debuglevel
IF options.!debug == 1 THEN SAY time()" _rpcnetsharegetinfo() started"
server = arg(1)
username = arg(2)
password = arg(3)
share = arg(4)
call VRSet VRWindow(), 'Pointer', 'Wait'
say ' 'samba.!rpcclientexe' 'server' --user='username'%'password' --command="netsharegetinfo 'share'" 'debuglevel' '
address cmd samba.!rpcclientexe' 'server' --user='username'%'password' --command="netsharegetinfo 'share'" 'debuglevel' >'samba.!msg
call VRSet VRWindow(), 'Pointer', ''
rpc.netsharegetinfo. = ""
Failure = 0
SIGNAL ON SYNTAX NAME RPCERROR
do until lines(samba.!msg) = 0
rpcline = linein(samba.!msg)
if pos("creating default valid table",rpcline) <> 0 then iterate
if pos("LOGON_FAILURE", rpcline) > 0 then do
Failure = 1
leave
end
parse var rpcline token ':' tvalue
token = translate(strip(strip(translate(token),'L','09'x)),'_',' ')
tvalue= strip(strip(tvalue,'L','09'x))
if pos('ACL',Token) = 0 & pos('ACE',Token) = 0 & pos('---',Token) = 0 & Token <> "" then do
if Token = "TYPE" & left(Tvalue,2) = "0x" & length(Tvalue) = 3 then Token = "SHARETYPE"
if Token = "TYPE" & pos("SEC",Tvalue) > 1 then Token = "SECTYPE"
dyn = 'rpc.netsharegetinfo.'Token' = "'Tvalue'"'
say " "dyn
interpret dyn
end
end
SIGNAL OFF SYNTAX
ok = stream(samba.!msg,'c','close')
ok = SysFileDelete(samba.!msg)
if Failure = 0 then do
retval = '1'
rpc.netsharegetinfo.LOGONSTATUS="OK"
end
else do
retval = '0 '
rpc.netsharegetinfo.LOGONSTATUS=substr(rpcline,pos("NT_STATUS",rpcline),)
end
IF options.!debug == 1 THEN SAY time()" _rpcnetsharegetinfo() done, "retval" "rpc.netsharegetinfo.LOGONSTATUS
return retval
/*:VRX _rpcquerygroupmem
*/
_rpcquerygroupmem: procedure expose rpc. samba. options. debuglevel
IF options.!debug == 1 THEN SAY time()" _rpcquerygroupmem() started"
server = arg(1)
username = arg(2)
password = arg(3)
grouprid = arg(4)
say ' 'samba.!rpcclientexe' 'server' --user='username'%'password' --command="querygroupmem 'grouprid'" 'debuglevel' '
address cmd samba.!rpcclientexe' 'server' --user='username'%'password' --command="querygroupmem 'grouprid'" 'debuglevel' >'samba.!msg
rpc.querygroupmem. = ""
Failure = 0
count = 0
SIGNAL ON SYNTAX NAME RPCERROR
do until lines(samba.!msg) = 0
rpcline = linein(samba.!msg)
if pos("creating default valid table",rpcline) <> 0 then iterate
if pos("LOGON_FAILURE", rpcline) > 0 then do
Failure = 1
leave
end
parse var rpcline 'rid:['trid'] attr:['tattr']'
token = translate(strip(strip(translate(token),'L','09'x)),'_',' ')
tvalue= strip(strip(tvalue,'L','09'x))
count = count + 1
dyn = 'rpc.querygroupmem.'count'.RID = "'Trid'"'
say " "dyn
interpret dyn
dyn = 'rpc.querygroupmem.'count'.ATTR = "'Tattr'"'
say " "dyn
interpret dyn
end
SIGNAL OFF SYNTAX
ok = stream(samba.!msg,'c','close')
ok = SysFileDelete(samba.!msg)
rpc.querygroupmem.0 = count
if Failure = 0 then do
retval = 1
rpc.querygroupmem.LOGONSTATUS="OK"
end
else do
retval = 0
rpc.querygroupmem.LOGONSTATUS=substr(rpcline,pos("NT_STATUS",rpcline),)
end
IF options.!debug == 1 THEN SAY time()" _rpcquerygroupmem() done, "retval" "rpc.querygroupmem.LOGONSTATUS
return retval
/*:VRX _rpcqueryuser
*/
_rpcqueryuser: procedure expose rpc. samba. options. debuglevel
IF options.!debug == 1 THEN SAY time()" _rpcqueryuser() started"
server = arg(1)
username = arg(2)
password = arg(3)
userrid = arg(4)
call VRSet VRWindow(), 'Pointer', 'Wait'
say ' 'samba.!rpcclientexe' 'server' --user='username'%'password' --command="queryuser 'userrid'" 'debuglevel' '
address cmd samba.!rpcclientexe' 'server' --user='username'%'password' --command="queryuser 'userrid'" 'debuglevel' >'samba.!msg
call VRSet VRWindow(), 'Pointer', ''
rpc.queryuser. = ""
Failure = 0
SIGNAL ON SYNTAX NAME RPCERROR
do until lines(samba.!msg) = 0
rpcline = linein(samba.!msg)
if pos("creating default valid table",rpcline) <> 0 then iterate
if pos("NT_STATUS", rpcline) > 0 then do
Failure = 1
leave
end
if pos("TDB(", translate(rpcline)) > 0 then do
Failure = 1
/* provide a fake NT_STATUS */
rpcline = 'NT_STATUS_TDBERROR 'rpcline
leave
end
parse var rpcline token ':' tvalue
token = translate(strip(strip(translate(token),'L','09'x)),'_',' ')
tvalue= strip(strip(tvalue,'L','09'x))
if pos('[',Token) = 0 & pos('TABLE',Token) = 0 & Token <> "" then do
dyn = 'rpc.queryuser.'Token' = "'Tvalue'"'
say " "dyn
interpret dyn
end
end
SIGNAL OFF SYNTAX
ok = stream(samba.!msg,'c','close')
ok = SysFileDelete(samba.!msg)
if Failure = 0 then do
retval = 1
rpc.queryuser.LOGONSTATUS="OK"
end
else do
retval = '0 '
rpc.queryuser.LOGONSTATUS=substr(rpcline,pos("NT_STATUS",rpcline),)
end
IF options.!debug == 1 THEN SAY time()" _rpcqueryuser() done, "retval" "rpc.queryuser.LOGONSTATUS
return retval
/*:VRX _rpcsrvinfo
*/
_rpcsrvinfo: procedure expose rpc. samba. options. debuglevel tempdir
IF options.!debug == 1 THEN SAY time()" _rpcsrvinfo() started"
server = arg(1)
username = arg(2)
password = arg(3)
/* Initialize temporary files */
rpcinfo.!msg = SysTempFileName(TempDir||"rpcinfo_msg.???")
rpcinfo.!err = SysTempFileName(TempDir||"rpcinfo_err.???")
ok = stream(rpcinfo.!msg,'c','close')
ok = stream(rpcinfo.!err,'c','close')
ok = SysFileDelete(rpcinfo.!msg)
ok = SysFileDelete(rpcinfo.!err)
usercred = '--user='username'%'password
if UserCred = 'USERCRED' | UserCred = '' | UserCred = '--user=%' then UserCred = '-N'
call VRSet VRWindow(), 'Pointer', 'Wait'
say ' 'samba.!rpcclientexe' 'server' 'usercred' --command="srvinfo" 'debuglevel' 2>'rpcinfo.!err' 1>'rpcinfo.!msg
address cmd samba.!rpcclientexe' 'server' 'usercred' --command="srvinfo" 'debuglevel' 2>'rpcinfo.!err' 1>'rpcinfo.!msg
call VRSet VRWindow(), 'Pointer', ''
rpc.srvinfo. = ""
Failure = 0
do while lines(rpcinfo.!err) > 0
rpcline = linein(rpcinfo.!err)
IF options.!debug == 1 THEN say " "rpcinfo.!err': "'rpcline'"'
if pos("UNSUCCESSFUL", translate(rpcline)) > 0 | pos("CANNOT CONNECT", translate(rpcline)) > 0 then do
ok = stream(rpcinfo.!msg,'c','close')
ok = stream(rpcinfo.!err,'c','close')
ok = SysFileDelete(rpcinfo.!msg)
ok = SysFileDelete(rpcinfo.!err)
Failure = 1
retval = 0
rpc.srvinfo. = ""
rpc.srvinfo.LOGONSTATUS=substr(rpcline,pos("NT_STATUS",rpcline),)
IF options.!debug == 1 THEN SAY time()" _rpcsrvinfo() aborted, "retval
return retval
end
end
SIGNAL ON SYNTAX NAME RPCERROR
do until lines(rpcinfo.!msg) = 0
rpcline = linein(rpcinfo.!msg)
if pos("creating default valid table",rpcline) <> 0 then iterate
if pos("TDB(",translate(rpcline)) <> 0 then iterate
if pos("LOGON_FAILURE", rpcline) > 0 then do
Failure = 1
leave
end
if pos(':',rpcline) <> 0 then do
parse var rpcline token ':' tvalue
token = translate(strip(strip(translate(token),'L','09'x)),'_',' ')
tvalue= strip(strip(tvalue,'L','09'x))
dyn = 'rpc.srvinfo.'Token' = "'Tvalue'"'
say " "dyn
interpret dyn
end
else do
parse var rpcline '09'x rpc.srvinfo.NETBIOSNAME' 'rpc.srvinfo.SERVERSTRING
rpc.srvinfo.SERVERSTRING = strip(rpc.srvinfo.SERVERSTRING)
say ' rpc.srvinfo.NETBIOSNAME = "'rpc.srvinfo.NETBIOSNAME'"'
say ' rpc.srvinfo.SERVERSTRING = "'rpc.srvinfo.SERVERSTRING'"'
rpc.srvinfo.CAPABILITIES = ""
do I = 1 to words(rpc.srvinfo.SERVERSTRING)
/* say "Word "I":"word(rpc.srvinfo.SERVERSTRING,I) */
if length(word(rpc.srvinfo.SERVERSTRING,I)) >=4 then leave
if length(word(rpc.srvinfo.SERVERSTRING,I)) = 2 | length(word(rpc.srvinfo.SERVERSTRING,I)) = 3 then do
rpc.srvinfo.CAPABILITIES = rpc.srvinfo.CAPABILITIES||word(rpc.srvinfo.SERVERSTRING,I)||' '
end
end
if rpc.srvinfo.CAPABILITIES <> "" then do
rpc.srvinfo.SERVERSTRING = strip(substr(rpc.srvinfo.SERVERSTRING,length(rpc.srvinfo.CAPABILITIES),))
rpc.srvinfo.CAPABILITIES = strip(rpc.srvinfo.CAPABILITIES)
end
say ' rpc.srvinfo.CAPABILITIES = "'rpc.srvinfo.CAPABILITIES'"'
say ' rpc.srvinfo.SERVERSTRING = "'rpc.srvinfo.SERVERSTRING'"'
end
end
SIGNAL OFF SYNTAX
ok = stream(rpcinfo.!msg,'c','close')
ok = stream(rpcinfo.!err,'c','close')
ok = SysFileDelete(rpcinfo.!msg)
ok = SysFileDelete(rpcinfo.!err)
if Failure = 0 then do
retval = 1
rpc.srvinfo.LOGONSTATUS="OK"
end
else do
retval = 0
rpc.srvinfo. = ""
rpc.srvinfo.LOGONSTATUS=substr(rpcline,pos("NT_STATUS",rpcline),)
end
say ' rpc.srvinfo.LOGONSTATUS = "'rpc.srvinfo.LOGONSTATUS'"'
IF options.!debug == 1 THEN SAY time()" _rpcsrvinfo() done, "retval
return retval
RPCERROR:
ok = stream(rpcinfo.!msg,'c','close')
ok = stream(rpcinfo.!err,'c','close')
ok = SysFileDelete(rpcinfo.!msg)
ok = SysFileDelete(rpcinfo.!err)
say " rpc parsing error in line "sigl": "strip(sourceline(sigl))
retval = -1
IF options.!debug == 1 THEN SAY time()" _rpclibrary aborted, "retval
return retval