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
138 def __cinit__(self, cell=None, sec=1):
140 cdef afsconf_dir *cdir
141 cdef afsconf_cell info
143 cdef ktc_principal prin
145 cdef rx_securityClass *sc
146 cdef rx_connection *serverconns[MAXSERVERS]
149 initialize_PT_error_table()
160 raise Exception(code, "Error initializing Rx")
162 cdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH)
165 "Error opening configuration directory (%s): %s" % \
166 (AFSDIR_CLIENT_ETC_DIRPATH, strerror(errno)))
167 code = afsconf_GetCellInfo(cdir, c_cell, "afsprot", &info)
171 strncpy(prin.cell, info.name, sizeof(prin.cell))
173 strncpy(prin.name, "afs", sizeof(prin.name))
175 code = ktc_GetToken(&prin, &token, sizeof(token), NULL);
178 # No really - we wanted authentication
186 sc = rxkad_NewClientSecurityObject(level, &token.sessionKey,
187 token.kvno, token.ticketLen,
191 sc = rxnull_NewClientSecurityObject()
195 memset(serverconns, 0, sizeof(serverconns))
196 for 0 <= i < info.numServers:
197 serverconns[i] = rx_NewConnection(info.hostAddr[i].sin_addr.s_addr,
198 info.hostAddr[i].sin_port,
203 code = ubik_ClientInit(serverconns, &self.client)
206 code = rxs_Release(sc)
208 def __dealloc__(self):
209 ubik_ClientDestroy(self.client)
212 def NameOrId(self, ident):
214 Given an identifier, convert it to a PTS ID by looking up the
215 name if it's a string, or otherwise just converting it to an
218 if isinstance(ident, (str, unicode)):
219 return self.NameToId(ident)
223 def NameToId(self, name):
225 Converts a user or group to an AFS ID.
229 cdef afs_int32 code, id = ANONYMOUSID
233 lids.idlist_val = NULL
234 lnames.namelist_len = 1
235 lnames.namelist_val = <prname *>malloc(PR_MAXNAMELEN)
236 strncpy(lnames.namelist_val[0], name, PR_MAXNAMELEN)
237 code = ubik_PR_NameToID(self.client, 0, &lnames, &lids)
238 if lids.idlist_val is not NULL:
239 id = lids.idlist_val[0]
240 free(lids.idlist_val)
241 if id == ANONYMOUSID:
246 def IdToName(self, id):
248 Convert an AFS ID to the name of a user or group.
253 cdef char name[PR_MAXNAMELEN]
256 lids.idlist_val = <afs_int32 *>malloc(sizeof(afs_int32))
257 lids.idlist_val[0] = id
258 lnames.namelist_len = 0
259 lnames.namelist_val = NULL
260 code = ubik_PR_IDToName(self.client, 0, &lids, &lnames)
261 if lnames.namelist_val is not NULL:
262 strncpy(name, lnames.namelist_val[0], sizeof(name))
263 free(lnames.namelist_val)
264 if lids.idlist_val is not NULL:
265 free(lids.idlist_val)
271 def CreateUser(self, name, id=None):
273 Create a new user in the protection database. If an ID is
274 provided, that one will be used.
278 name = name[:PR_MAXNAMELEN].lower()
284 code = ubik_PR_INewEntry(self.client, 0, name, cid, 0)
286 code = ubik_PR_NewEntry(self.client, 0, name, 0, 0, &cid)
291 def CreateGroup(self, name, owner, id=None):
293 Create a new group in the protection database. If an ID is
294 provided, that one will be used.
296 cdef afs_int32 code, cid
298 name = name[:PR_MAXNAMELEN].lower()
299 oid = self.NameOrId(owner)
303 code = ubik_PR_INewEntry(self.client, 0, name, cid, oid)
305 code = ubik_PR_NewEntry(self.client, 0, name, PRGRP, oid, &cid)
310 def Delete(self, ident):
312 Delete the protection database entry with the provided
316 cdef afs_int32 id = self.NameOrId(ident)
318 code = ubik_PR_Delete(self.client, 0, id)
321 def AddToGroup(self, user, group):
323 Add the given user to the given group.
326 cdef afs_int32 uid = self.NameOrId(user), gid = self.NameOrId(group)
328 code = ubik_PR_AddToGroup(self.client, 0, uid, gid)
331 def RemoveFromGroup(self, user, group):
333 Remove the given user from the given group.
336 cdef afs_int32 uid = self.NameOrId(user), gid = self.NameOrId(group)
338 code = ubik_PR_RemoveFromGroup(self.client, 0, uid, gid)
341 def ListMembers(self, ident):
343 Get the membership of an entity.
345 If id is a group, this returns the users that are in that
348 If id is a user, this returns the list of groups that user is
351 This returns a list of PTS IDs.
353 cdef afs_int32 code, over
356 cdef object members = []
358 cdef afs_int32 id = self.NameOrId(ident)
361 alist.prlist_val = NULL
363 code = ubik_PR_ListElements(self.client, 0, id, &alist, &over)
365 if alist.prlist_val is not NULL:
366 for i in range(alist.prlist_len):
367 members.append(alist.prlist_val[i])
368 free(alist.prlist_val)
376 def ListOwned(self, owner):
378 Get all groups owned by an entity.
380 cdef afs_int32 code, over
383 cdef object owned = []
385 cdef afs_int32 oid = self.NameOrId(owner)
388 alist.prlist_val = NULL
390 code = ubik_PR_ListOwned(self.client, 0, oid, &alist, &over)
392 if alist.prlist_val is not NULL:
393 for i in range(alist.prlist_len):
394 owned.append(alist.prlist_val[i])
395 free(alist.prlist_val)
403 def ListEntry(self, ident):
405 Load a PTEntry instance with information about the provided
409 cdef prcheckentry centry
410 cdef object entry = PTEntry()
412 cdef afs_int32 id = self.NameOrId(ident)
414 code = ubik_PR_ListEntry(self.client, 0, id, ¢ry)
417 _ptentry_from_c(entry, ¢ry)
420 def ChangeEntry(self, ident, newname=None, newid=None, newoid=None):
422 Change the name, ID, and/or owner of a PTS entity.
424 For any of newname, newid, and newoid which aren't specified
425 or ar None, the value isn't changed.
428 cdef afs_int32 c_newid = 0, c_newoid = 0
429 cdef char * c_newname
431 cdef afs_int32 id = self.NameOrId(ident)
434 newname = self.IdToName(id)
436 if newid is not None:
438 if newoid is not None:
441 code = ubik_PR_ChangeEntry(self.client, 0, id, c_newname, c_newoid, c_newid)
444 def IsAMemberOf(self, user, group):
446 Return True if the given user is a member of the given group.
451 cdef afs_int32 uid = self.NameOrId(user), gid = self.NameOrId(group)
453 code = ubik_PR_IsAMemberOf(self.client, 0, uid, gid, &flag)
460 Return a tuple of the maximum user ID and the maximum group
461 ID currently assigned.
463 cdef afs_int32 code, uid, gid
465 code = ubik_PR_ListMax(self.client, 0, &uid, &gid)
470 def SetMaxUserId(self, id):
472 Set the maximum currently assigned user ID (the next
473 automatically assigned UID will be id + 1)
477 code = ubik_PR_SetMax(self.client, 0, id, 0)
480 def SetMaxGroupId(self, id):
482 Set the maximum currently assigned user ID (the next
483 automatically assigned UID will be id + 1)
487 code = ubik_PR_SetMax(self.client, 0, id, PRGRP)
490 def ListEntries(self, users=None, groups=None):
492 Return a list of PTEntry instances representing all entries in
495 Returns just users by default, but can return just users, just
499 cdef afs_int32 flag = 0, startindex = 0, nentries, nextstartindex
500 cdef prentries centries
503 cdef object entries = []
505 if groups is None or users is True:
510 while startindex != -1:
511 centries.prentries_val = NULL
512 centries.prentries_len = 0
515 code = ubik_PR_ListEntries(self.client, 0, flag, startindex, ¢ries, &nextstartindex)
516 if centries.prentries_val is not NULL:
517 for i in range(centries.prentries_len):
519 _ptentry_from_c(e, <prcheckentry *>¢ries.prentries_val[i])
521 free(centries.prentries_val)
524 startindex = nextstartindex
528 def SetFields(self, ident, access=None, groups=None, users=None):
530 Update the fields for an entry.
532 Valid fields are the privacy flags (access), the group quota
533 (groups), or the "foreign user quota" (users), which doesn't
534 actually seem to do anything, but is included for
538 cdef afs_int32 mask = 0, flags = 0, nusers = 0, ngroups = 0
540 cdef afs_int32 id = self.NameOrId(ident)
542 if access is not None:
544 mask |= PR_SF_ALLBITS
545 if groups is not None:
547 mask |= PR_SF_NGROUPS
548 if users is not None:
550 mask |= PR_SF_NGROUPS
552 code = ubik_PR_SetFieldsEntry(self.client, 0, id, mask, flags, ngroups, nusers, 0, 0)