-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy path_moira.pyx
208 lines (172 loc) · 5.4 KB
/
_moira.pyx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
cdef extern from "moira/moira.h":
int mr_krb5_auth(char * prog)
int mr_auth(char * prog)
int mr_connect(char * server)
int mr_disconnect()
int mr_host(char * host_buf, int buf_size)
int mr_motd(char ** motd)
int mr_noop()
int mr_query(char * handle, int argc, char ** argv,
int (*callback)(int, char **, void *), object callarg)
int mr_access(char *handle, int argc, char ** argv)
int mr_proxy(char *principal, char *orig_authtype)
int mr_version(int version)
enum:
MR_SUCCESS
MR_CONT
MR_VERSION_LOW
cdef extern from "com_err.h":
ctypedef long errcode_t
char * error_message(errcode_t)
cdef extern from "stdlib.h":
ctypedef unsigned long size_t
void * malloc(size_t size)
void free(void * ptr)
class MoiraException(Exception):
def code(self):
return self.args[0]
code = property(code)
__connected = False
def _error(code):
raise MoiraException, (code, error_message(code))
def connect(server=''):
"""
Establish a connection to a Moira server.
A server may be specified, but it is optional. If specified, it
should be of the form hostname:portname. Portname will be looked
up in /etc/services if specified, but it is optional as well.
If no server is specified, the server will be found from the
MOIRASERVER environment variable, Hesiod, or a compiled in default
(in that order).
This function raises a MoiraException if the connection is
not successful.
"""
global __connected
if __connected:
disconnect()
status = mr_connect(server)
if status != MR_SUCCESS:
_error(status)
else:
__connected = True
def disconnect():
"""
Disconnect from the active Moira server
"""
global __connected
if __connected:
mr_disconnect()
__connected = False
def auth(program, krb4=False):
"""
Authenticate to the Moira server with Kerberos tickets. If krb4 is
True, then Kerberos version 4 will be used. Otherwise, Kerberos
version 5 is used.
The program argument identifies the connecting program to the
Moira server. This is used for setting the modwith field when
modifications are made.
Note that the use of Kerberos version 4 is deprecated and highly
discouraged
"""
if krb4:
status = mr_auth(program)
else:
status = mr_krb5_auth(program)
if status != MR_SUCCESS:
_error(status)
def host():
"""
Return the name of the host the client is connected to.
"""
cdef char buffer[512]
status = mr_host(buffer, 512)
if status != MR_SUCCESS:
_error(status)
return buffer
def motd():
"""
Retrieve the current message of the day from the server.
"""
cdef char * motd
status = mr_motd(&motd)
if status != MR_SUCCESS:
_error(status)
if motd != NULL:
return motd
def noop():
"""
Does "no operation" to the server, just making sure it's still
there
"""
status = mr_noop()
if status:
_error(status)
def _access(handle, *args):
"""
Verifies that the authenticated user has the access to perform the
given query.
"""
cdef int argc, i
argc = len(args)
cdef char ** argv
argv = <char **>malloc(argc * sizeof(char *))
if argv != NULL:
for i in xrange(argc):
argv[i] = args[i]
status = mr_access(handle, argc, argv)
free(argv)
if status:
_error(status)
def _query(handle, callback, *args):
cdef int argc, i
argc = len(args)
cdef char ** argv
argv = <char **>malloc(argc * sizeof(char *))
if argv != NULL:
for i in xrange(argc):
argv[i] = args[i]
status = mr_query(handle, argc, argv, _call_python_callback, callback)
free(argv)
if status:
_error(status)
def proxy(principal, orig_authtype):
"""
Authenticate as a proxy for another principal.
For those with sufficient privilege, proxy allows an authenticated
user to impersonate another.
The principal argument contains the Kerberos principal for which
this user is proxying, and orig_authtype is the mechanism by which
the proxied user originally authenticated to the proxier.
"""
status = mr_proxy(principal, orig_authtype)
if status != MR_SUCCESS:
_error(status)
def version(ver):
"""
Exchange query version info with the server.
In order to allow changing queries without breaking client
compatibility, the Moira server supports multiple versions of the
query list simultaneously. Use version to change which one is
currently being used.
The ver argument is a signed integer containing the query version
to use. If ver is -1, Moira will always use the more recent query
version.
version returns True if you requested the most recent version
number and False if you requested an out-of-date version number.
"""
status = mr_version(ver)
if status == MR_SUCCESS:
return True
elif status == MR_VERSION_LOW:
return False
else:
_error(status)
cdef int _call_python_callback(int argc, char ** argv, void * hint):
cdef object callback
callback = <object>hint
result = []
cdef int i
for i in xrange(argc):
result.append(argv[i])
callback(tuple(result))
return MR_CONT