2 from afs import pyafs_error
4 cdef import from "afs/ptuser.h":
15 ctypedef char prname[PR_MAXNAMELEN]
18 unsigned int namelist_len
22 unsigned int prlist_len
26 unsigned int idlist_len
37 char name[PR_MAXNAMELEN]
47 char name[PR_MAXNAMELEN]
50 unsigned int prentries_len
51 prlistentries *prentries_val
53 int ubik_PR_NameToID(ubik_client *, afs_int32, namelist *, idlist *)
54 int ubik_PR_IDToName(ubik_client *, afs_int32, idlist *, namelist *)
55 int ubik_PR_INewEntry(ubik_client *, afs_int32, char *, afs_int32, afs_int32)
56 int ubik_PR_NewEntry(ubik_client *, afs_int32, char *, afs_int32, afs_int32, afs_int32 *)
57 int ubik_PR_Delete(ubik_client *, afs_int32, afs_int32)
58 int ubik_PR_AddToGroup(ubik_client *, afs_int32, afs_int32, afs_int32)
59 int ubik_PR_RemoveFromGroup(ubik_client *, afs_int32, afs_int32, afs_int32)
60 int ubik_PR_ListElements(ubik_client *, afs_int32, afs_int32, prlist *, afs_int32 *)
61 int ubik_PR_ListOwned(ubik_client *, afs_int32, afs_int32, prlist *, afs_int32 *)
62 int ubik_PR_ListEntry(ubik_client *, afs_int32, afs_int32, prcheckentry *)
63 int ubik_PR_ChangeEntry(ubik_client *, afs_int32, afs_int32, char *, afs_int32, afs_int32)
64 int ubik_PR_IsAMemberOf(ubik_client *, afs_int32, afs_int32, afs_int32, afs_int32 *)
65 int ubik_PR_ListMax(ubik_client *, afs_int32, afs_int32 *, afs_int32 *)
66 int ubik_PR_SetMax(ubik_client *, afs_int32, afs_int32, afs_int32)
67 int ubik_PR_ListEntries(ubik_client *, afs_int32, afs_int32, afs_int32, prentries *, afs_int32 *)
68 int ubik_PR_SetFieldsEntry(ubik_client *, afs_int32, afs_int32, afs_int32, afs_int32, afs_int32, afs_int32, afs_int32, afs_int32)
70 cdef import from "afs/pterror.h":
76 cdef public afs_int32 flags
77 cdef public afs_int32 id
78 cdef public afs_int32 owner
79 cdef public afs_int32 creator
80 cdef public afs_int32 ngroups
81 cdef public afs_int32 nusers
82 cdef public afs_int32 count
83 cdef public object name
87 return '<PTEntry: %s>' % self.name
89 return '<PTEntry: PTS ID %s>' % self.id
91 cdef int _ptentry_from_c(PTEntry p_entry, prcheckentry * c_entry) except -1:
96 p_entry.flags = c_entry.flags
97 p_entry.id = c_entry.id
98 p_entry.owner = c_entry.owner
99 p_entry.creator = c_entry.creator
100 p_entry.ngroups = c_entry.ngroups
101 p_entry.nusers = c_entry.nusers
102 p_entry.count = c_entry.count
103 p_entry.name = c_entry.name
106 cdef int _ptentry_to_c(prcheckentry * c_entry, PTEntry p_entry) except -1:
111 c_entry.flags = p_entry.flags
112 c_entry.id = p_entry.id
113 c_entry.owner = p_entry.owner
114 c_entry.creator = p_entry.creator
115 c_entry.ngroups = p_entry.ngroups
116 c_entry.nusers = p_entry.nusers
117 c_entry.count = p_entry.count
118 strncpy(c_entry.name, p_entry.name, sizeof(c_entry.name))
123 A PTS object is essentially a handle to talk to the server in a
126 cell defaults to None. If no argument is passed for cell, PTS
127 connects to the home cell.
129 sec is the security level, an integer from 0 to 3:
130 - 0: unauthenticated connection
131 - 1: try authenticated, then fall back to unauthenticated
132 - 2: fail if an authenticated connection can't be established
133 - 3: same as 2, plus encrypt all traffic to the protection
136 cdef ubik_client * client
137 cdef readonly object cell
139 def __cinit__(self, cell=None, sec=1):
141 cdef afsconf_dir *cdir
142 cdef afsconf_cell info
144 cdef ktc_principal prin
146 cdef rx_securityClass *sc
147 cdef rx_connection *serverconns[MAXSERVERS]
150 initialize_PT_error_table()
161 raise Exception(code, "Error initializing Rx")
163 cdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH)
166 "Error opening configuration directory (%s): %s" % \
167 (AFSDIR_CLIENT_ETC_DIRPATH, strerror(errno)))
168 code = afsconf_GetCellInfo(cdir, c_cell, "afsprot", &info)
171 self.cell = info.name
174 strncpy(prin.cell, info.name, sizeof(prin.cell))
176 strncpy(prin.name, "afs", sizeof(prin.name))
178 code = ktc_GetToken(&prin, &token, sizeof(token), NULL);
181 # No really - we wanted authentication
189 sc = rxkad_NewClientSecurityObject(level, &token.sessionKey,
190 token.kvno, token.ticketLen,
194 sc = rxnull_NewClientSecurityObject()
198 memset(serverconns, 0, sizeof(serverconns))
199 for 0 <= i < info.numServers:
200 serverconns[i] = rx_NewConnection(info.hostAddr[i].sin_addr.s_addr,
201 info.hostAddr[i].sin_port,
206 code = ubik_ClientInit(serverconns, &self.client)
209 code = rxs_Release(sc)
211 def __dealloc__(self):
212 ubik_ClientDestroy(self.client)
215 def _NameOrId(self, ident):
217 Given an identifier, convert it to a PTS ID by looking up the
218 name if it's a string, or otherwise just converting it to an
221 if isinstance(ident, (str, unicode)):
222 return self._NameToId(ident)
226 def _NameToId(self, name):
228 Converts a user or group to an AFS ID.
232 cdef afs_int32 code, id = ANONYMOUSID
236 lids.idlist_val = NULL
237 lnames.namelist_len = 1
238 lnames.namelist_val = <prname *>malloc(PR_MAXNAMELEN)
239 strncpy(lnames.namelist_val[0], name, PR_MAXNAMELEN)
240 code = ubik_PR_NameToID(self.client, 0, &lnames, &lids)
241 if lids.idlist_val is not NULL:
242 id = lids.idlist_val[0]
243 free(lids.idlist_val)
244 if id == ANONYMOUSID:
249 def _IdToName(self, id):
251 Convert an AFS ID to the name of a user or group.
256 cdef char name[PR_MAXNAMELEN]
259 lids.idlist_val = <afs_int32 *>malloc(sizeof(afs_int32))
260 lids.idlist_val[0] = id
261 lnames.namelist_len = 0
262 lnames.namelist_val = NULL
263 code = ubik_PR_IDToName(self.client, 0, &lids, &lnames)
264 if lnames.namelist_val is not NULL:
265 strncpy(name, lnames.namelist_val[0], sizeof(name))
266 free(lnames.namelist_val)
267 if lids.idlist_val is not NULL:
268 free(lids.idlist_val)
274 def _CreateUser(self, name, id=None):
276 Create a new user in the protection database. If an ID is
277 provided, that one will be used.
281 name = name[:PR_MAXNAMELEN].lower()
287 code = ubik_PR_INewEntry(self.client, 0, name, cid, 0)
289 code = ubik_PR_NewEntry(self.client, 0, name, 0, 0, &cid)
294 def _CreateGroup(self, name, owner, id=None):
296 Create a new group in the protection database. If an ID is
297 provided, that one will be used.
299 cdef afs_int32 code, cid
301 name = name[:PR_MAXNAMELEN].lower()
302 oid = self._NameOrId(owner)
306 code = ubik_PR_INewEntry(self.client, 0, name, cid, oid)
308 code = ubik_PR_NewEntry(self.client, 0, name, PRGRP, oid, &cid)
313 def _Delete(self, ident):
315 Delete the protection database entry with the provided
319 cdef afs_int32 id = self._NameOrId(ident)
321 code = ubik_PR_Delete(self.client, 0, id)
324 def _AddToGroup(self, user, group):
326 Add the given user to the given group.
329 cdef afs_int32 uid = self._NameOrId(user), gid = self._NameOrId(group)
331 code = ubik_PR_AddToGroup(self.client, 0, uid, gid)
334 def _RemoveFromGroup(self, user, group):
336 Remove the given user from the given group.
339 cdef afs_int32 uid = self._NameOrId(user), gid = self._NameOrId(group)
341 code = ubik_PR_RemoveFromGroup(self.client, 0, uid, gid)
344 def _ListMembers(self, ident):
346 Get the membership of an entity.
348 If id is a group, this returns the users that are in that
351 If id is a user, this returns the list of groups that user is
354 This returns a list of PTS IDs.
356 cdef afs_int32 code, over
359 cdef object members = []
361 cdef afs_int32 id = self._NameOrId(ident)
364 alist.prlist_val = NULL
366 code = ubik_PR_ListElements(self.client, 0, id, &alist, &over)
368 if alist.prlist_val is not NULL:
369 for i in range(alist.prlist_len):
370 members.append(alist.prlist_val[i])
371 free(alist.prlist_val)
379 def _ListOwned(self, owner):
381 Get all groups owned by an entity.
383 cdef afs_int32 code, over
386 cdef object owned = []
388 cdef afs_int32 oid = self._NameOrId(owner)
391 alist.prlist_val = NULL
393 code = ubik_PR_ListOwned(self.client, 0, oid, &alist, &over)
395 if alist.prlist_val is not NULL:
396 for i in range(alist.prlist_len):
397 owned.append(alist.prlist_val[i])
398 free(alist.prlist_val)
406 def _ListEntry(self, ident):
408 Load a PTEntry instance with information about the provided
412 cdef prcheckentry centry
413 cdef object entry = PTEntry()
415 cdef afs_int32 id = self._NameOrId(ident)
417 code = ubik_PR_ListEntry(self.client, 0, id, ¢ry)
420 _ptentry_from_c(entry, ¢ry)
423 def _ChangeEntry(self, ident, newname=None, newid=None, newoid=None):
425 Change the name, ID, and/or owner of a PTS entity.
427 For any of newname, newid, and newoid which aren't specified
428 or ar None, the value isn't changed.
431 cdef afs_int32 c_newid = 0, c_newoid = 0
432 cdef char * c_newname
434 cdef afs_int32 id = self._NameOrId(ident)
437 newname = self._IdToName(id)
439 if newid is not None:
441 if newoid is not None:
444 code = ubik_PR_ChangeEntry(self.client, 0, id, c_newname, c_newoid, c_newid)
447 def _IsAMemberOf(self, user, group):
449 Return True if the given user is a member of the given group.
454 cdef afs_int32 uid = self._NameOrId(user), gid = self._NameOrId(group)
456 code = ubik_PR_IsAMemberOf(self.client, 0, uid, gid, &flag)
463 Return a tuple of the maximum user ID and the maximum group
464 ID currently assigned.
466 cdef afs_int32 code, uid, gid
468 code = ubik_PR_ListMax(self.client, 0, &uid, &gid)
473 def _SetMaxUserId(self, id):
475 Set the maximum currently assigned user ID (the next
476 automatically assigned UID will be id + 1)
480 code = ubik_PR_SetMax(self.client, 0, id, 0)
483 def _SetMaxGroupId(self, id):
485 Set the maximum currently assigned user ID (the next
486 automatically assigned UID will be id + 1)
490 code = ubik_PR_SetMax(self.client, 0, id, PRGRP)
493 def _ListEntries(self, users=None, groups=None):
495 Return a list of PTEntry instances representing all entries in
498 Returns just users by default, but can return just users, just
502 cdef afs_int32 flag = 0, startindex = 0, nentries, nextstartindex
503 cdef prentries centries
506 cdef object entries = []
508 if groups is None or users is True:
513 while startindex != -1:
514 centries.prentries_val = NULL
515 centries.prentries_len = 0
518 code = ubik_PR_ListEntries(self.client, 0, flag, startindex, ¢ries, &nextstartindex)
519 if centries.prentries_val is not NULL:
520 for i in range(centries.prentries_len):
522 _ptentry_from_c(e, <prcheckentry *>¢ries.prentries_val[i])
524 free(centries.prentries_val)
527 startindex = nextstartindex
531 def _SetFields(self, ident, access=None, groups=None, users=None):
533 Update the fields for an entry.
535 Valid fields are the privacy flags (access), the group quota
536 (groups), or the "foreign user quota" (users), which doesn't
537 actually seem to do anything, but is included for
541 cdef afs_int32 mask = 0, flags = 0, nusers = 0, ngroups = 0
543 cdef afs_int32 id = self._NameOrId(ident)
545 if access is not None:
547 mask |= PR_SF_ALLBITS
548 if groups is not None:
550 mask |= PR_SF_NGROUPS
551 if users is not None:
553 mask |= PR_SF_NGROUPS
555 code = ubik_PR_SetFieldsEntry(self.client, 0, id, mask, flags, ngroups, nusers, 0, 0)