local csv_path = "d:/userlist.csv" --the csv file path local domain = "domain1" --the domain name do local function check_int(n) if(n - math.floor(n) > 0) then error("trying to use bitwise operation on non-integer!") end end local function to_bits(n) check_int(n) if(n < 0) then return to_bits(bit.bnot(math.abs(n)) + 1) end local tbl = {} local cnt = 1 while (n > 0) do local last = math.mod(n,2) if(last == 1) then tbl[cnt] = 1 else tbl[cnt] = 0 end n = (n-last)/2 cnt = cnt + 1 end return tbl end local function tbl_to_number(tbl) local n = table.getn(tbl) local rslt = 0 local power = 1 for i = 1, n do rslt = rslt + tbl[i]*power power = power*2 end return rslt end local function expand(tbl_m, tbl_n) local big = {} local small = {} if(table.getn(tbl_m) > table.getn(tbl_n)) then big = tbl_m small = tbl_n else big = tbl_n small = tbl_m end for i = table.getn(small) + 1, table.getn(big) do small[i] = 0 end end local function bit_and(m, n) local tbl_m = to_bits(m) local tbl_n = to_bits(n) expand(tbl_m, tbl_n) local tbl = {} local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n)) for i = 1, rslt do if(tbl_m[i]== 0 or tbl_n[i] == 0) then tbl[i] = 0 else tbl[i] = 1 end end local result = tbl_to_number(tbl) if result > 0 then return true else return false end end bit = { band = bit_and, tobits = to_bits, tonumb = tbl_to_number, } end function fromCSV(s) s = s .. ',' local t = {} local fieldstart = 1 repeat if string.find(s, '^"', fieldstart) then local a, c local i = fieldstart repeat a, i, c = string.find(s, '"("?)', i+1) until c ~= '"' if not i then error('unmatched "') end local f = string.sub(s, fieldstart+1, i-1) local nexti = i+1 table.insert(t, (string.gsub(f, '""', '"'))) fieldstart = nexti + 1 else local nexti = string.find(s, ',', fieldstart) local temp = string.sub(s, fieldstart, nexti-1) local n = string.find(temp, '\n', 1) if n then temp = string.sub(temp, 1, n-1) nexti = fieldstart+n-1 end table.insert(t, temp) fieldstart = nexti+1 end until fieldstart > string.len(s) return t end --get the content of csv file local fp = assert(io.open(csv_path, "r")) local content = fp:read("*all") local n = string.find(content, '\n') local temp = string.sub(content, 1, n-1) fp:close() local colnum = 104 --fields number of csv file if temp ~= nil then colnum = table.maxn(Split(temp, ",")) end local LoginID, Password, HomeDir, Enabled, FTP, HTTP, SSH, QuotaBytes, MaxSessionsIPPerUser, MaxSessionsPerUser, Quota, SSHPublicKeyFilePath, SessTimeoutSeconds, DirAccess, VirtualPath, IPAccess,EnableExpiration,ExpiredTime,NoteString local t = fromCSV(content) for i, s in ipairs(t) do if colnum == 104 then -- Serv-U 15.0 if i % colnum == 1 then LoginID = s elseif i % colnum == 10 then Password = s elseif i % colnum == 12 then NoteString = s elseif i % colnum == 14 then EnableExpiration = s elseif i % colnum == 15 then ExpiredTime = s elseif i % colnum == 41 then HomeDir = string.gsub(s, "\\","/") elseif i % colnum == 32 then Enabled = s elseif i % colnum == 33 then FTP = s elseif i % colnum == 36 then HTTP = s elseif i % colnum == 83 then SSH = s elseif i % colnum == 17 then QuotaBytes = s elseif i % colnum == 50 then MaxSessionsIPPerUser = s elseif i % colnum == 51 then MaxSessionsPerUser = s elseif i % colnum == 65 then Quota = s elseif i % colnum == 85 then SSHPublicKeyFilePath = string.gsub(s, "\\","/") elseif i % colnum == 87 then SessTimeoutSeconds = s elseif i % colnum == 95 then DirAccess = string.gsub(s, "\\","/") elseif i % colnum == 96 then VirtualPath = string.gsub(s, "\\","/") elseif i % colnum == 97 then IPAccess = s end elseif colnum == 119 then -- Serv-U 15.1 if i % colnum == 1 then LoginID = s elseif i % colnum == 10 then Password = s elseif i % colnum == 12 then NoteString = s elseif i % colnum == 14 then EnableExpiration = s elseif i % colnum == 15 then ExpiredTime = s elseif i % colnum == 48 then HomeDir = string.gsub(s, "\\","/") elseif i % colnum == 39 then Enabled = s elseif i % colnum == 40 then FTP = s elseif i % colnum == 43 then HTTP = s elseif i % colnum == 97 then SSH = s elseif i % colnum == 17 then QuotaBytes = s elseif i % colnum == 59 then MaxSessionsIPPerUser = s elseif i % colnum == 60 then MaxSessionsPerUser = s elseif i % colnum == 77 then Quota = s elseif i % colnum == 102 then SessTimeoutSeconds = s elseif i % colnum == 110 then DirAccess = string.gsub(s, "\\","/") elseif i % colnum == 111 then VirtualPath = string.gsub(s, "\\","/") elseif i % colnum == 112 then IPAccess = s end elseif colnum == 86 then if i % colnum == 1 then LoginID = s elseif i % colnum == 7 then Password = s elseif i % colnum == 31 then HomeDir = string.gsub(s, "\\","/") elseif i % colnum == 24 then Enabled = s elseif i % colnum == 25 then FTP = s elseif i % colnum == 26 then HTTP = s elseif i % colnum == 66 then SSH = s elseif i % colnum == 13 then QuotaBytes = s elseif i % colnum == 39 then MaxSessionsIPPerUser = s elseif i % colnum == 40 then MaxSessionsPerUser = s elseif i % colnum == 51 then Quota = s elseif i % colnum == 69 then SessTimeoutSeconds = s elseif i % colnum == 77 then DirAccess = string.gsub(s, "\\","/") elseif i % colnum == 78 then VirtualPath = string.gsub(s, "\\","/") elseif i % colnum == 79 then IPAccess = s end elseif colnum == 90 then if i % colnum == 1 then LoginID = s elseif i % colnum == 7 then Password = s elseif i % colnum == 33 then HomeDir = string.gsub(s, "\\","/") elseif i % colnum == 26 then Enabled = s elseif i % colnum == 27 then FTP = s elseif i % colnum == 28 then HTTP = s elseif i % colnum == 69 then SSH = s elseif i % colnum == 13 then QuotaBytes = s elseif i % colnum == 42 then MaxSessionsIPPerUser = s elseif i % colnum == 43 then MaxSessionsPerUser = s elseif i % colnum == 54 then Quota = s elseif i % colnum == 73 then SessTimeoutSeconds = s elseif i % colnum == 81 then DirAccess = string.gsub(s, "\\","/") elseif i % colnum == 82 then VirtualPath = string.gsub(s, "\\","/") elseif i % colnum == 83 then IPAccess = s end elseif colnum == 99 then if i % colnum == 1 then LoginID = s elseif i % colnum == 10 then Password = s elseif i % colnum == 38 then HomeDir = string.gsub(s, "\\","/") elseif i % colnum == 31 then Enabled = s elseif i % colnum == 32 then FTP = s elseif i % colnum == 33 then HTTP = s elseif i % colnum == 78 then SSH = s elseif i % colnum == 17 then QuotaBytes = s elseif i % colnum == 47 then MaxSessionsIPPerUser = s elseif i % colnum == 48 then MaxSessionsPerUser = s elseif i % colnum == 62 then Quota = s elseif i % colnum == 82 then SessTimeoutSeconds = s elseif i % colnum == 90 then DirAccess = string.gsub(s, "\\","/") elseif i % colnum == 91 then VirtualPath = string.gsub(s, "\\","/") elseif i % colnum == 92 then IPAccess = s end elseif colnum == 103 then if i % colnum == 1 then LoginID = s elseif i % colnum == 10 then Password = s elseif i % colnum == 40 then HomeDir = string.gsub(s, "\\","/") elseif i % colnum == 31 then Enabled = s elseif i % colnum == 32 then FTP = s elseif i % colnum == 35 then HTTP = s elseif i % colnum == 82 then SSH = s elseif i % colnum == 17 then QuotaBytes = s elseif i % colnum == 49 then MaxSessionsIPPerUser = s elseif i % colnum == 50 then MaxSessionsPerUser = s elseif i % colnum == 64 then Quota = s elseif i % colnum == 84 then SSHPublicKeyFilePath = string.gsub(s, "\\","/") elseif i % colnum == 86 then SessTimeoutSeconds = s elseif i % colnum == 94 then DirAccess = string.gsub(s, "\\","/") elseif i % colnum == 95 then VirtualPath = string.gsub(s, "\\","/") elseif i % colnum == 96 then IPAccess = s end end --not reading the firt line if i > colnum and i % colnum == 0 then local Protocols = 0 if FTP ~= "0" then Protocols = Protocols + 1 + 2 + 4 end if HTTP ~= "0" then Protocols = Protocols + 8 + 16 end if SSH ~= "0" then Protocols = Protocols + 32 end if SessTimeoutSeconds ~= nil and SessTimeoutSeconds ~= "" then SessTimeoutSeconds = math.ceil(tonumber(SessTimeoutSeconds) / 60) end if Enabled == "0" then Enabled = 0 else Enabled = 1 end local endtime = os.date("%Y-%m-%d %H:%M:%S", os.time()) if ExpiredTime ~= nil and ExpiredTime ~= "" then endtime = os.date("%Y-%m-%d %H:%M:%S", tonumber(ExpiredTime)) end local expiration = 0 if EnableExpiration ~= nil and EnableExpiration == "1" then expiration = 1 end local enableSSHPublicKey = 0 local SSHPublicKeyMethod = 0 if SSHPublicKeyFilePath ~= nil and SSHPublicKeyFilePath ~= "" then enableSSHPublicKey = 1 SSHPublicKeyMethod = 1 end local arrDirAccess = Split(DirAccess, ",") local nItems = tonumber(arrDirAccess[1]) local nFields = 4 local nNowIndex = 1 local DirPem = {} for n=0,nItems-1 do nFields = tonumber(arrDirAccess[nNowIndex+1]) if nFields == 2 then DirPem[arrDirAccess[nNowIndex+3]] = 7967 else DirPem[arrDirAccess[nNowIndex+3]] = tonumber(arrDirAccess[nNowIndex+5]) if table.maxn(arrDirAccess) == 8 and (QuotaBytes == nil or QuotaBytes == "") then QuotaBytes = tonumber(arrDirAccess[nNowIndex+7]) end end nNowIndex = nNowIndex + tonumber(arrDirAccess[nNowIndex+1]) + 1 end local enablequota = 0 local diskquota = 0 if QuotaBytes ~= nil and QuotaBytes ~= "" then enablequota = 1 diskquota = QuotaBytes/1024 end if c_UserExist(domain,username) == false then -- add user account c_AddUser(domain,LoginID,Password,Protocols,1,Enabled,0,0,MaxSessionsPerUser,SessTimeoutSeconds,0,MaxSessionsIPPerUser,0,1,1,1,0,0,0,0,0,0,diskquota,enablequota,"","","","","","",NoteString,0,0,0,0,1,0,0,0,0,0,0,0,0,expiration,endtime,0,0,SSHPublicKeyFilePath,0,enableSSHPublicKey,SSHPublicKeyMethod) -- add user directory local folderPerm = DirPem[HomeDir] or DirPem["%HOME%"] if folderPerm ~= nil then c_AddUserDirectory(domain, LoginID, HomeDir, '/', true, bit.band(folderPerm,1), bit.band(folderPerm,2), bit.band(folderPerm,4), bit.band(folderPerm,8), bit.band(folderPerm,256), bit.band(folderPerm,512), bit.band(folderPerm,1024), bit.band(folderPerm,2048), bit.band(folderPerm,16)) end if VirtualPath ~= nil and VirtualPath ~= "" then local arrVirtualPath = Split(VirtualPath, ",") local nItems2 = tonumber(arrVirtualPath[1]) for n=0,nItems2-1 do local strRealPath = arrVirtualPath[n*5+4] local strVirtualPath = arrVirtualPath[n*5+6] strVirtualPath = string.gsub(strVirtualPath,"%%HOME%%","") if string.find(string.reverse(strVirtualPath),"/") then strVirtualPath = string.sub(strVirtualPath,1-string.find(string.reverse(strVirtualPath),"/")) end if DirPem[strRealPath] ~= nil then c_AddUserDirectory(domain, LoginID, strRealPath, strVirtualPath, false, bit.band(DirPem[strRealPath],1), bit.band(DirPem[strRealPath],2), bit.band(DirPem[strRealPath],4), bit.band(DirPem[strRealPath],8), bit.band(DirPem[strRealPath],256), bit.band(DirPem[strRealPath],512), bit.band(DirPem[strRealPath],1024), bit.band(DirPem[strRealPath],2048), bit.band(DirPem[strRealPath],16)) end end end end end end print("Imported user accounts successfully!")