def _init_with_grp(self, grp_entry): if isinstance(grp_entry, grp.struct_group): for key in self._gr_map.keys(): setattr(self,key,getattr(grp_entry, self._gr_map[key])) if self.gid is not None: # Group exists, find extended information id_auth = CBIdentityAuthority.defaultIdentityAuthority() self._id_obj = CBGroupIdentity.groupIdentityWithPosixGID_authority_(self.gid, id_auth) if self._id_obj: # Make copies of the data as pure python objects, rather than keep translating if self._id_obj.UUIDString() is not None: self.uuid = str(self._id_obj.UUIDString()) if self._id_obj.fullName() is not None: self.fullname = str(self._id_obj.fullName()) self.hidden = bool(self._id_obj.isHidden())
def get_groups(username): # verify user exists defaultAuth = CBIdentityAuthority.defaultIdentityAuthority() the_user = CBUserIdentity.identityWithName_authority_(username, defaultAuth) if (the_user != None): user_details = identity_dict(the_user) posix_details = posix_user(user_details['posixName']) libc = CDLL("/usr/lib/libSystem.B.dylib") # define access to an undocumented Apple function 'getgrouplist_2' # Based on the example from: # http://opensource.apple.com/source/shell_cmds/shell_cmds-162/id/id.c getgrouplist_2 = libc.getgrouplist_2 getgrouplist_2.argtypes = [c_char_p, c_uint32, POINTER(POINTER(c_uint32))] groups = POINTER(c_uint32)() ngroups = getgrouplist_2(user_details['posixName'], posix_details['gid'], byref(groups)) # make explicit copies prior to freeing the allocated pointer array group_list = [(0+groups[i]) for i in range(ngroups)] # clean up after ourselves _ = libc.free(groups) for g in group_list: full_group = CBGroupIdentity.groupIdentityWithPosixGID_authority_(g, defaultAuth) yield identity_dict(full_group)
def _init_with_pwd(self, pwd_entry): if isinstance(pwd_entry, pwd.struct_passwd): for key in self._pw_map.keys(): setattr(self,key,getattr(pwd_entry, self._pw_map[key])) if self.uid is not None: # User exists, find extended information id_auth = CBIdentityAuthority.defaultIdentityAuthority() self._id_obj = CBUserIdentity.userIdentityWithPosixUID_authority_(self.uid, id_auth) if self._id_obj: # Make copies of the data as pure python objects, rather than keep translating if self._id_obj.emailAddress() is not None: self.email = str(self._id_obj.emailAddress()) if self._id_obj.UUIDString() is not None: self.uuid = str(self._id_obj.UUIDString()) if self._id_obj.fullName() is not None: self.fullname = str(self._id_obj.fullName()) self.hidden = bool(self._id_obj.isHidden()) self.enabled = bool(self._id_obj.isEnabled()) # Find extended group membership information # Load up OS X libc libc = CDLL("/usr/lib/libc.dylib") # define access to an undocumented Apple function 'getgrouplist_2' # Based on the example from: # http://opensource.apple.com/source/shell_cmds/shell_cmds-162/id/id.c getgrouplist_2 = libc.getgrouplist_2 # Create the function prototype getgrouplist_2.argtypes = [c_char_p, c_uint32, POINTER(POINTER(c_uint32))] # Initialize pointer to array of gid information groups = POINTER(c_uint32)() # Get number of groups and gid list ngroups = getgrouplist_2(self.name, self.gid, byref(groups)) # Make explicit copies prior to freeing the allocated pointer array if ngroups > 0: self.groups = [Group(int(groups[i])) for i in range(ngroups)] # Clean up after ourselves and free up the array, ignoring result _ = libc.free(groups)
# Based on the example from: # http://opensource.apple.com/source/shell_cmds/shell_cmds-162/id/id.c getgrouplist_2 = libc.getgrouplist_2 getgrouplist_2.argtypes = [c_char_p, c_uint32, POINTER(POINTER(c_uint32))] groups = POINTER(c_uint32)() ngroups = getgrouplist_2(user_details['posixName'], posix_details['gid'], byref(groups)) # make explicit copies prior to freeing the allocated pointer array group_list = [(0+groups[i]) for i in range(ngroups)] # clean up after ourselves _ = libc.free(groups) for g in group_list: full_group = CBGroupIdentity.groupIdentityWithPosixGID_authority_(g, defaultAuth) yield identity_dict(full_group) # get pseudo authority that represents local + directory services defaultAuth = CBIdentityAuthority.defaultIdentityAuthority() ### Testing group, user, and membership username, groupname = ("root", "wheel") print "Test: User: %s, Group: %s" % (username, groupname) # attempt to find user in question user = CBUserIdentity.identityWithName_authority_(username, defaultAuth) if not user: print "Error: Unable to find user:"******"User details:", user print "User dict:", identity_dict(user)
def cmdBuild_(self, args): """Build image""" # Parse arguments. sourcePath = IEDUtil.installESDPath_(args.source) or \ IEDUtil.systemImagePath_(args.source) if sourcePath: templatePath = None else: templatePath = self.checkTemplate_(args.source) if not sourcePath and not templatePath: self.failWithMessage_( "'%s' is not a valid OS X installer, OS X system image or AutoDMG template" % args.source) return os.EX_DATAERR if templatePath: template = IEDTemplate.alloc().init() error = template.loadTemplateAndReturnError_(templatePath) if error: self.failWithMessage_("Couldn't load template from '%s': %s" % (templatePath, error)) return os.EX_DATAERR else: template = IEDTemplate.alloc().initWithSourcePath_(sourcePath) if args.installer: template.setSourcePath_(args.installer) if args.output: template.setOutputPath_(args.output) if args.name: template.setVolumeName_(args.name) if args.size: template.setVolumeSize_(args.size) if args.skip_asr_imagescan: template.setFinalizeAsrImagescan_(False) if args.filesystem: template.setFilesystem_(args.filesystem) if args.updates is not None: template.setApplyUpdates_(True) if args.packages: if not template.setAdditionalPackages_(args.packages): self.failWithMessage_( "Additional packages failed verification: %s" % template.additionalPackageError) return os.EX_DATAERR if not template.sourcePath: self.failWithMessage_("No source path") return os.EX_USAGE if not template.outputPath: self.failWithMessage_("No output path") return os.EX_USAGE LogNotice("Installer: %@", template.sourcePath) # Set the source. self.busy = True self.workflow.setSource_(template.sourcePath) self.waitBusy() if self.hasFailed: return os.EX_DATAERR template.resolveVariables_({ "OSNAME": self.installerName, "OSVERSION": self.installerVersion, "OSBUILD": self.installerBuild, }) LogNotice("Output Path: %@", template.outputPath) LogNotice("Volume Name: %@", template.volumeName) # Generate the list of updates to install. updates = list() if template.applyUpdates: profile = self.profileController.profileForVersion_Build_( self.installerVersion, self.installerBuild) if profile is None: self.failWithMessage_( self.profileController.whyNoProfileForVersion_build_( self.installerVersion, self.installerBuild)) return os.EX_DATAERR missingUpdates = list() for update in profile: LogNotice("Update: %@ (%@)", update["name"], IEDUtil.formatByteSize_(update["size"])) package = IEDPackage.alloc().init() package.setName_(update["name"]) package.setPath_(self.cache.updatePath_(update["sha1"])) package.setSize_(update["size"]) package.setUrl_(update["url"]) package.setSha1_(update["sha1"]) if not self.cache.isCached_(update["sha1"]): if args.download_updates: missingUpdates.append(package) else: self.failWithMessage_( "Can't apply updates, %s is missing from cache" % update["name"]) return os.EX_DATAERR updates.append(package) if missingUpdates: self.cache.downloadUpdates_(missingUpdates) self.busy = True self.waitBusy() if self.hasFailed: self.failWithMessage_( "Can't build due to updates missing from cache") return 1 # EXIT_FAILURE updates.extend(missingUpdates) LogNotice("All updates for %@ %@ downloaded", self.installerVersion, self.installerBuild) # Generate the list of additional packages to install. template.resolvePackages() for package in template.packagesToInstall: LogNotice("Package: %@ (%@)", package.name(), IEDUtil.formatByteSize_(package.size())) # Check the output path. if os.path.exists(template.outputPath): if args.force: try: os.unlink(template.outputPath) except OSError as e: self.failWithMessage_("Couldn't remove %s: %s" % (template.outputPath, str(e))) return os.EX_CANTCREAT else: self.failWithMessage_("%s already exists" % template.outputPath) return os.EX_CANTCREAT else: outputDir = os.path.dirname(template.outputPath) if outputDir and not os.path.exists(outputDir): try: os.makedirs(outputDir) except OSError as e: self.failWithMessage_( "%s does not exist and can't be created: %s" % (outputDir, str(e))) return os.EX_CANTCREAT # If we're not running as root get the password for authentication. if os.getuid() != 0: username = NSUserName() currentUser = CBIdentity.identityWithName_authority_( username, CBIdentityAuthority.defaultIdentityAuthority()) passwordOK = False while not passwordOK: password = getpass.getpass("Password for %s: " % username).decode("utf-8") if currentUser.authenticateWithPassword_(password): passwordOK = True self.workflow.setAuthUsername_(username) self.workflow.setAuthPassword_(password) # Start the workflow. self.busy = True self.workflow.setPackagesToInstall_(updates + template.packagesToInstall) self.workflow.setOutputPath_(template.outputPath) self.workflow.setVolumeName_(template.volumeName) self.workflow.setVolumeSize_(template.volumeSize) self.workflow.setFinalizeAsrImagescan_(template.finalizeAsrImagescan) self.workflow.setFilesystem_(template.filesystem) self.workflow.setTemplate_(template) self.workflow.start() self.waitBusy() if self.hasFailed: return 1 # EXIT_FAILURE return os.EX_OK
def cmdBuild_(self, args): """Build image""" # Parse arguments. sourcePath = IEDUtil.installESDPath_(args.source) if sourcePath: templatePath = None else: templatePath = self.checkTemplate_(args.source) if not sourcePath and not templatePath: self.failWithMessage_(u"'%s' is not a valid OS X installer or AutoDMG template" % args.source) return os.EX_DATAERR if templatePath: template = IEDTemplate.alloc().init() error = template.loadTemplateAndReturnError_(templatePath) if error: self.failWithMessage_(u"Couldn't load template from '%s': %s" % (templatePath, error)) return os.EX_DATAERR else: template = IEDTemplate.alloc().initWithSourcePath_(sourcePath) if args.installer: template.setSourcePath_(args.installer) if args.output: template.setOutputPath_(args.output) if args.name: template.setVolumeName_(args.name) if args.size: template.setVolumeSize_(args.size) if args.updates is not None: template.setApplyUpdates_(True) if args.packages: if not template.setAdditionalPackages_(args.packages): self.failWithMessage_(u"Additional packages failed verification") return os.EX_DATAERR if not template.sourcePath: self.failWithMessage_(u"No source path") return os.EX_USAGE if not template.outputPath: self.failWithMessage_(u"No output path") return os.EX_USAGE LogNotice(u"Installer: %@", template.sourcePath) # Set the source. self.busy = True self.workflow.setSource_(template.sourcePath) self.waitBusy() if self.hasFailed: return os.EX_DATAERR template.resolveVariables_({ u"OSNAME": self.installerName, u"OSVERSION": self.installerVersion, u"OSBUILD": self.installerBuild, }) LogNotice(u"Output Path: %@", template.outputPath) LogNotice(u"Volume Name: %@", template.volumeName) # Generate the list of updates to install. updates = list() if template.applyUpdates: profile = self.profileController.profileForVersion_Build_(self.installerVersion, self.installerBuild) if profile is None: self.failWithMessage_(self.profileController.whyNoProfileForVersion_build_(self.installerVersion, self.installerBuild)) return os.EX_DATAERR missingUpdates = list() for update in profile: LogNotice(u"Update: %@ (%@)", update[u"name"], IEDUtil.formatBytes_(update[u"size"])) package = IEDPackage.alloc().init() package.setName_(update[u"name"]) package.setPath_(self.cache.updatePath_(update[u"sha1"])) package.setSize_(update[u"size"]) package.setUrl_(update[u"url"]) package.setSha1_(update[u"sha1"]) if not self.cache.isCached_(update[u"sha1"]): if args.download_updates: missingUpdates.append(package) else: self.failWithMessage_(u"Can't apply updates, %s is missing from cache" % update[u"name"]) return os.EX_DATAERR updates.append(package) if missingUpdates: self.cache.downloadUpdates_(missingUpdates) self.busy = True self.waitBusy() if self.hasFailed: self.failWithMessage_(u"Can't build due to updates missing from cache") return 1 # EXIT_FAILURE updates.extend(missingUpdates) LogNotice(u"All updates for %@ %@ downloaded", self.installerVersion, self.installerBuild) # Generate the list of additional packages to install. template.resolvePackages() for package in template.packagesToInstall: LogNotice(u"Package: %@ (%@)", package.name(), IEDUtil.formatBytes_(package.size())) # Check the output path. if os.path.exists(template.outputPath): if args.force: try: os.unlink(template.outputPath) except OSError as e: self.failWithMessage_(u"Couldn't remove %s: %s" % (template.outputPath, unicode(e))) return os.EX_CANTCREAT else: self.failWithMessage_(u"%s already exists" % template.outputPath) return os.EX_CANTCREAT else: outputDir = os.path.dirname(template.outputPath) if outputDir and not os.path.exists(outputDir): try: os.makedirs(outputDir) except OSError as e: self.failWithMessage_(u"%s does not exist and can't be created: %s" % (outputDir, unicode(e))) return os.EX_CANTCREAT # If we're not running as root get the password for authentication. if os.getuid() != 0: username = NSUserName() currentUser = CBIdentity.identityWithName_authority_(username, CBIdentityAuthority.defaultIdentityAuthority()) passwordOK = False while not passwordOK: password = getpass.getpass(u"Password for %s: " % username).decode(u"utf-8") if currentUser.authenticateWithPassword_(password): passwordOK = True self.workflow.setAuthUsername_(username) self.workflow.setAuthPassword_(password) # Start the workflow. self.busy = True self.workflow.setPackagesToInstall_(updates + template.packagesToInstall) self.workflow.setOutputPath_(template.outputPath) self.workflow.setVolumeName_(template.volumeName) self.workflow.setVolumeSize_(template.volumeSize) self.workflow.setTemplate_(template) self.workflow.start() self.waitBusy() if self.hasFailed: return 1 # EXIT_FAILURE return os.EX_OK