3 cdef import from "afs/ptuser.h":
14 ctypedef char prname[PR_MAXNAMELEN]
17 unsigned int namelist_len
21 unsigned int prlist_len
25 unsigned int idlist_len
36 char name[PR_MAXNAMELEN]
46 char name[PR_MAXNAMELEN]
49 unsigned int prentries_len
50 prlistentries *prentries_val
52 int ubik_PR_NameToID(ubik_client *, afs_int32, namelist *, idlist *)
53 int ubik_PR_IDToName(ubik_client *, afs_int32, idlist *, namelist *)
54 int ubik_PR_INewEntry(ubik_client *, afs_int32, char *, afs_int32, afs_int32)
55 int ubik_PR_NewEntry(ubik_client *, afs_int32, char *, afs_int32, afs_int32, afs_int32 *)
56 int ubik_PR_Delete(ubik_client *, afs_int32, afs_int32)
57 int ubik_PR_AddToGroup(ubik_client *, afs_int32, afs_int32, afs_int32)
58 int ubik_PR_RemoveFromGroup(ubik_client *, afs_int32, afs_int32, afs_int32)
59 int ubik_PR_ListElements(ubik_client *, afs_int32, afs_int32, prlist *, afs_int32 *)
60 int ubik_PR_ListOwned(ubik_client *, afs_int32, afs_int32, prlist *, afs_int32 *)
61 int ubik_PR_ListEntry(ubik_client *, afs_int32, afs_int32, prcheckentry *)
62 int ubik_PR_ChangeEntry(ubik_client *, afs_int32, afs_int32, char *, afs_int32, afs_int32)
63 int ubik_PR_IsAMemberOf(ubik_client *, afs_int32, afs_int32, afs_int32, afs_int32 *)
64 int ubik_PR_ListMax(ubik_client *, afs_int32, afs_int32 *, afs_int32 *)
65 int ubik_PR_SetMax(ubik_client *, afs_int32, afs_int32, afs_int32)
66 int ubik_PR_ListEntries(ubik_client *, afs_int32, afs_int32, afs_int32, prentries *, afs_int32 *)
67 int ubik_PR_SetFieldsEntry(ubik_client *, afs_int32, afs_int32, afs_int32, afs_int32, afs_int32, afs_int32, afs_int32, afs_int32)
69 cdef import from "afs/pterror.h":
74 void initialize_PT_error_table()
77 cdef public afs_int32 flags
78 cdef public afs_int32 id
79 cdef public afs_int32 owner
80 cdef public afs_int32 creator
81 cdef public afs_int32 ngroups
82 cdef public afs_int32 nusers
83 cdef public afs_int32 count
84 cdef public object name
88 return '<PTEntry: %s>' % self.name
90 return '<PTEntry: PTS ID %s>' % self.id
92 cdef int _ptentry_from_c(PTEntry p_entry, prcheckentry * c_entry) except -1:
97 p_entry.flags = c_entry.flags
98 p_entry.id = c_entry.id
99 p_entry.owner = c_entry.owner
100 p_entry.creator = c_entry.creator
101 p_entry.ngroups = c_entry.ngroups
102 p_entry.nusers = c_entry.nusers
103 p_entry.count = c_entry.count
104 p_entry.name = c_entry.name
107 cdef int _ptentry_to_c(prcheckentry * c_entry, PTEntry p_entry) except -1:
112 c_entry.flags = p_entry.flags
113 c_entry.id = p_entry.id
114 c_entry.owner = p_entry.owner
115 c_entry.creator = p_entry.creator
116 c_entry.ngroups = p_entry.ngroups
117 c_entry.nusers = p_entry.nusers
118 c_entry.count = p_entry.count
119 strncpy(c_entry.name, p_entry.name, sizeof(c_entry.name))
124 A PTS object is essentially a handle to talk to the server in a
127 cell defaults to None. If no argument is passed for cell, PTS
128 connects to the home cell.
130 sec is the security level, an integer from 0 to 3:
131 - 0: unauthenticated connection
132 - 1: try authenticated, then fall back to unauthenticated
133 - 2: fail if an authenticated connection can't be established
134 - 3: same as 2, plus encrypt all traffic to the protection
137 cdef ubik_client * client
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)
170 raise Exception(code, "GetCellInfo: %s" % afs_error_message(code))
173 strncpy(prin.cell, info.name, sizeof(prin.cell))
175 strncpy(prin.name, "afs", sizeof(prin.name))
177 code = ktc_GetToken(&prin, &token, sizeof(token), NULL);
180 # No really - we wanted authentication
181 raise Exception(code, "Failed to get token for service AFS: %s" % afs_error_message(code))
188 sc = rxkad_NewClientSecurityObject(level, &token.sessionKey,
189 token.kvno, token.ticketLen,
193 sc = rxnull_NewClientSecurityObject()
197 memset(serverconns, 0, sizeof(serverconns))
198 for 0 <= i < info.numServers:
199 serverconns[i] = rx_NewConnection(info.hostAddr[i].sin_addr.s_addr,
200 info.hostAddr[i].sin_port,
205 code = ubik_ClientInit(serverconns, &self.client)
207 raise Exception("Failed to initialize ubik connection to Protection server: %s" % afs_error_message(code))
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
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:
247 raise Exception("Failed to lookup PTS name: %s" % afs_error_message(code))
250 def IdToName(self, id):
252 Convert an AFS ID to the name of a user or group.
257 cdef char name[PR_MAXNAMELEN]
260 lids.idlist_val = <afs_int32 *>malloc(sizeof(afs_int32))
261 lids.idlist_val[0] = id
262 lnames.namelist_len = 0
263 lnames.namelist_val = NULL
264 code = ubik_PR_IDToName(self.client, 0, &lids, &lnames)
265 if lnames.namelist_val is not NULL:
266 strncpy(name, lnames.namelist_val[0], sizeof(name))
267 free(lnames.namelist_val)
268 if lids.idlist_val is not NULL:
269 free(lids.idlist_val)
273 raise Exception("Failed to lookup PTS ID: %s" % afs_error_message(code))
276 def CreateUser(self, name, id=None):
278 Create a new user in the protection database. If an ID is
279 provided, that one will be used.
283 name = name[:PR_MAXNAMELEN].lower()
289 code = ubik_PR_INewEntry(self.client, 0, name, cid, 0)
291 code = ubik_PR_NewEntry(self.client, 0, name, 0, 0, &cid)
294 raise Exception("Failed to create user: %s" % afs_error_message(code))
297 def CreateGroup(self, name, owner, id=None):
299 Create a new group in the protection database. If an ID is
300 provided, that one will be used.
302 cdef afs_int32 code, cid
304 name = name[:PR_MAXNAMELEN].lower()
305 oid = self.NameToId(owner)
309 code = ubik_PR_INewEntry(self.client, 0, name, cid, oid)
311 code = ubik_PR_NewEntry(self.client, 0, name, PRGRP, oid, &cid)
314 raise Exception("Failed to create group: %s" % afs_error_message(code))
317 def Delete(self, id):
319 Delete the protection database entry with the provided ID.
323 code = ubik_PR_Delete(self.client, 0, id)
325 raise Exception("Failed to delete user: %s" % afs_error_message(code))
327 def AddToGroup(self, uid, gid):
329 Add the user with the given ID to the group with the given ID.
333 code = ubik_PR_AddToGroup(self.client, 0, uid, gid)
335 raise Exception("Failed to add user to group: %s" % afs_error_message(code))
337 def RemoveFromGroup(self, uid, gid):
339 Remove the user with the given ID from the group with the given ID.
343 code = ubik_PR_RemoveFromGroup(self.client, 0, uid, gid)
345 raise Exception("Failed to remove user from group: %s" % afs_error_message(code))
347 def ListMembers(self, id):
349 Get the membership of an entity.
351 If id is a group ID, this returns the users that are in that
354 If id is a user ID, this returns the list of groups that user
357 This returns a list of PTS IDs.
359 cdef afs_int32 code, over
362 cdef object members = []
365 alist.prlist_val = NULL
367 code = ubik_PR_ListElements(self.client, 0, id, &alist, &over)
369 if alist.prlist_val is not NULL:
370 for i in range(alist.prlist_len):
371 members.append(alist.prlist_val[i])
372 free(alist.prlist_val)
377 raise Exception("Failed to get group membership: %s" % afs_error_message(code))
381 def ListOwned(self, oid):
383 Get all groups owned by an entity.
385 cdef afs_int32 code, over
388 cdef object owned = []
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)
403 raise Exception("Failed to get owned entities: %s" % afs_error_message(code))
407 def ListEntry(self, id):
409 Load a PTEntry instance with information about the provided
413 cdef prcheckentry centry
414 cdef object entry = PTEntry()
416 code = ubik_PR_ListEntry(self.client, 0, id, ¢ry)
418 raise Exception("Error getting entity info: %s" % afs_error_message(code))
420 _ptentry_from_c(entry, ¢ry)
423 def ChangeEntry(self, id, 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
435 newname = self.IdToName(id)
437 if newid is not None:
439 if newoid is not None:
442 code = ubik_PR_ChangeEntry(self.client, 0, id, c_newname, c_newoid, c_newid)
444 raise Exception("Error changing entity info: %s" % afs_error_message(code))
446 def IsAMemberOf(self, uid, gid):
448 Return True if the given uid is a member of the given gid.
453 code = ubik_PR_IsAMemberOf(self.client, 0, uid, gid, &flag)
455 raise Exception("Error testing membership: %s" % afs_error_message(code))
461 Return a tuple of the maximum user ID and the maximum group
462 ID currently assigned.
464 cdef afs_int32 code, uid, gid
466 code = ubik_PR_ListMax(self.client, 0, &uid, &gid)
468 raise Exception("Error looking up max uid/gid: %s" % afs_error_message(code))
472 def SetMaxUserId(self, id):
474 Set the maximum currently assigned user ID (the next
475 automatically assigned UID will be id + 1)
479 code = ubik_PR_SetMax(self.client, 0, id, 0)
481 raise Exception("Error setting max uid: %s" % afs_error_message(code))
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)
492 raise Exception("Error setting max gid: %s" % afs_error_message(code))
494 def ListEntries(self, users=None, groups=None):
496 Return a list of PTEntry instances representing all entries in
499 Returns just users by default, but can return just users, just
503 cdef afs_int32 flag = 0, startindex = 0, nentries, nextstartindex
504 cdef prentries centries
507 cdef object entries = []
509 if groups is None or users is True:
514 while startindex != -1:
515 centries.prentries_val = NULL
516 centries.prentries_len = 0
519 code = ubik_PR_ListEntries(self.client, 0, flag, startindex, ¢ries, &nextstartindex)
520 if centries.prentries_val is not NULL:
521 for i in range(centries.prentries_len):
523 _ptentry_from_c(e, <prcheckentry *>¢ries.prentries_val[i])
525 free(centries.prentries_val)
527 raise Exception("Unable to list entries: %s" % afs_error_message(code))
529 startindex = nextstartindex
533 def SetFields(self, id, access=None, groups=None, users=None):
535 Update the fields for an entry.
537 Valid fields are the privacy flags (access), the group quota
538 (groups), or the "foreign user quota" (users), which doesn't
539 actually seem to do anything, but is included for
543 cdef afs_int32 mask = 0, flags = 0, nusers = 0, ngroups = 0
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)
557 raise Exception("Unable to set fields: %s" % afs_error_message(code))