1#!/usr/bin/env python3
2
3from __future__ import print_function
4import sys
5import os
6import subprocess
7from samba.compat import get_string
8
9
10if len(sys.argv) != 3:
11    print("Usage: test_wbinfo_sids2xids_int.py wbinfo net")
12    sys.exit(1)
13
14wbinfo = sys.argv[1]
15netcmd = sys.argv[2]
16
17
18def run(cmd):
19    """
20    Run a cmd, return bytes str for py2 and unicode str for py3.
21
22    NOTE: subprocess api always return bytes, in both py2 and py3.
23    """
24    output = subprocess.check_output(cmd).strip()
25    return get_string(output)
26
27
28def flush_cache(sids=[], uids=[], gids=[]):
29    for sid in sids:
30        os.system(netcmd + (" cache del IDMAP/SID2XID/%s" % (sid)))
31    for uids in uids:
32        os.system(netcmd + (" cache del IDMAP/UID2SID/%s" % (uid)))
33    for gids in gids:
34        os.system(netcmd + (" cache del IDMAP/GID2SID/%s" % (gid)))
35
36
37def fill_cache(inids, idtype='gid'):
38    for inid in inids:
39        if inid is None:
40            continue
41        run([wbinfo, '--%s-to-sid=%s' % (idtype, inid)])
42
43
44domain = run([wbinfo, "--own-domain"])
45domsid = run([wbinfo, "-n", domain + "/"])
46domsid = domsid.split(' ')[0]
47
48# print domain
49# print domsid
50
51sids = [domsid + '-512', 'S-1-5-32-545', domsid + '-513', 'S-1-1-0', 'S-1-3-1', 'S-1-5-1']
52
53flush_cache(sids=sids)
54
55sids2xids = run([wbinfo, '--sids-to-unix-ids=' + ','.join(sids)])
56
57gids = []
58uids = []
59idtypes = []
60
61for line in sids2xids.split('\n'):
62    result = line.split(' ')[2:]
63    idtypes.append(result[0])
64
65    gid = None
66    uid = None
67    if result[0] == 'gid':
68        gid = result[1]
69    elif result[0] == 'uid':
70        uid = result[1]
71    elif result[0] == 'uid/gid':
72        gid = result[1]
73        uid = result[1]
74
75    if gid == '-1':
76        gid = ''
77    gids.append(gid)
78
79    if uid == '-1':
80        uid = ''
81    uids.append(uid)
82
83# Check the list produced by the sids-to-xids call with the
84# singular variant (sid-to-xid) for each sid in turn.
85
86
87def check_singular(sids, ids, idtype='gid'):
88    i = 0
89    for sid in sids:
90        if ids[i] is None:
91            continue
92
93        outid = run([wbinfo, '--sid-to-%s' % idtype, sid])
94        if outid != ids[i]:
95            print("Expected %s, got %s\n" % (outid, ids[i]))
96            flush_cache(sids=sids, uids=uids, gids=gids)
97            sys.exit(1)
98        i += 1
99
100# Check the list produced by the sids-to-xids call with the
101# multiple variant (sid-to-xid) for each sid in turn.
102
103
104def check_multiple(sids, idtypes):
105    sids2xids = run([wbinfo, '--sids-to-unix-ids=' + ','.join(sids)])
106    # print sids2xids
107    i = 0
108    for line in sids2xids.split('\n'):
109        result = line.split(' ')[2:]
110
111        if result[0] != idtypes[i]:
112            print("Expected %s, got %s\n" % (idtypes[i], result[0]))
113            flush_cache(sids=sids, uids=uids, gids=gids)
114            sys.exit(1)
115        i += 1
116
117
118# first round: with filled cache via sid-to-id
119check_singular(sids, gids, 'gid')
120check_singular(sids, uids, 'uid')
121
122# second round: with empty cache
123flush_cache(sids=sids, gids=gids)
124check_singular(sids, gids, 'gid')
125flush_cache(sids=sids, uids=uids)
126check_singular(sids, uids, 'uid')
127
128# third round: with filled cache via uid-to-sid
129flush_cache(sids=uids, uids=uids)
130fill_cache(uids, 'uid')
131check_multiple(sids, idtypes)
132
133# fourth round: with filled cache via gid-to-sid
134flush_cache(sids=sids, gids=gids)
135fill_cache(gids, 'gid')
136check_multiple(sids, idtypes)
137
138# flush the cache so any incorrect mappings don't break other tests
139flush_cache(sids=sids, uids=uids, gids=gids)
140
141sys.exit(0)
142