// @pymethod ACCESS_MASK|PyACL|GetEffectiveRightsFromAcl|Return access rights (ACCESS_MASK) that the ACL grants to specified trustee PyObject *PyACL::PyGetEffectiveRightsFromAcl(PyObject *self, PyObject *args) { DWORD err=0; ACCESS_MASK access_mask=0; PyACL *This = (PyACL *)self; PyObject *ret=NULL, *obTrustee=NULL; TRUSTEE_W trustee; // @pyparm <o PyTRUSTEE>|trustee||Dictionary representing a TRUSTEE structure if (!PyArg_ParseTuple(args, "O:GetEffectiveRightsFromAcl", &obTrustee)) return NULL; if (!PyWinObject_AsTRUSTEE(obTrustee, &trustee)) return NULL; err=GetEffectiveRightsFromAclW(This->GetACL(), &trustee, &access_mask); if (err!=ERROR_SUCCESS) PyWin_SetAPIError("GetEffectiveRightsFromAcl",err); else ret=Py_BuildValue("l",access_mask); PyWinObject_FreeTRUSTEE(&trustee); return ret; }
/** stat a file on winnt - this is *very* painful **/ int win_filestat(stat_b *st, char *path, unsigned int want, unsigned int *give, char **err) { WIN32_FILE_ATTRIBUTE_DATA stat; SID_IDENTIFIER_AUTHORITY world_auth = SECURITY_WORLD_SID_AUTHORITY; PSID owner, group, world = NULL; PACL dacl; PSECURITY_DESCRIPTOR pdesc; int have_sec = 0; *give = 0; if (!GetFileAttributesEx(path, GetFileExInfoStandard, &stat)) { int ret, ecode = GetLastError(); *err = get_error_msg(ecode); switch (ecode) { case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: ret = FX_NO_SUCH_FILE; break; case ERROR_ACCESS_DENIED: ret = FX_PERMISSION_DENIED; break; default: ret = FX_FAILURE; } return ret; } /* create a PSID for well known group "world" - this is equivalent to "others" on POSIX */ if (!AllocateAndInitializeSid(&world_auth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &world)) world = NULL; memset(st, 0x0, sizeof(*st)); *give |= ATTR_SIZE; if (!(stat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) st->size = ((unsigned __int64)stat.nFileSizeHigh << 32) + (unsigned __int64)stat.nFileSizeLow; else st->size = 0; if (GetNamedSecurityInfo(path, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, &owner, &group, &dacl, NULL, &pdesc) != ERROR_SUCCESS) { ERR(have_sec, "Could not retrieve security info"); have_sec = 0; } else have_sec = 1; if (have_sec) { /* fake unix style uid & gid. We will do this by getting the string representations of the owner & group PIDS and converting them to numbers (hopefully unique) char *temp; ConvertSidToStringSid(owner, &temp); st->uid = st->gid = atol(temp); printf("(%s) sid = %l , %l\n", temp, st->uid, st->gid); LocalFree(temp); */ st->uid = st->gid = 42; *give |= ATTR_UIDGID; } /* not applicable for v3 - the commented code is for v6 if ((want & ATTR_UIDGID) & have_sec){ wchar_t uname[UNLEN + 1], dname[DNLEN + 1], gname[1000], gname2[1000]; DWORD unlen = UNLEN, dnlen = DNLEN, gnlen = 1000, gnlen2 = 1000; SID_NAME_USE stype; st->owner = malloc(UNLEN + DNLEN + 2); if (!LookupAccountSidW(NULL, owner, uname, &unlen, dname, &dnlen, &stype)) { ERR(GetLastError(), "Could not lookup ownername"); free(st->owner); st->owner = NULL; } else swprintf(st->owner, UNLEN + DNLEN + 2, L"%s@%s", uname, dname); st->group = malloc(UNLEN + DNLEN + 2 + 2000); if (!LookupAccountSidW(NULL, group, gname, &gnlen, gname2, &gnlen2, &stype)) { ERR(GetLastError(), "Could not lookup group name"); if (st->owner) swprintf(st->group, UNLEN + DNLEN + 2 + 2000, L"None@%", dname); else { free(st->group); st->group = NULL; } } else swprintf(st->group, UNLEN + DNLEN + 2 + 2000, L"%s@%s", gname, gname2); *give |= ATTR_OWNERGROUP; } */ st->perms = 0; st->perms |= stat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? FX_S_IFDIR : FX_S_IFREG; if (have_sec) { TRUSTEE_W ident = {NULL, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID}; ACCESS_MASK acc; ident.TrusteeType = TRUSTEE_IS_USER; ident.ptstrName = owner; if (GetEffectiveRightsFromAclW(dacl, &ident, &acc) == ERROR_SUCCESS) { if (acc & FILE_EXECUTE) st->perms |= FX_S_IXUSR; if (acc & FILE_WRITE_DATA) st->perms |= FX_S_IWUSR; if (acc & FILE_READ_DATA) st->perms |= FX_S_IRUSR; } ident.TrusteeType = TRUSTEE_IS_GROUP; ident.ptstrName = group; if (GetEffectiveRightsFromAclW(dacl, &ident, &acc) == ERROR_SUCCESS) { if (acc & FILE_EXECUTE) st->perms |= FX_S_IXGRP; if (acc & FILE_WRITE_DATA) st->perms |= FX_S_IWGRP; if (acc & FILE_READ_DATA) st->perms |= FX_S_IRGRP; } if (world) { ident.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ident.ptstrName = world; if (GetEffectiveRightsFromAclW(dacl, &ident, &acc) == ERROR_SUCCESS) { if (acc & FILE_EXECUTE) st->perms |= FX_S_IROTH; if (acc & FILE_WRITE_DATA) st->perms |= FX_S_IWOTH; if (acc & FILE_READ_DATA) st->perms |= FX_S_IROTH; } } /* we can't do shit about the S_ISUID, S_ISGUID & S_ISVTX flags */ *give |= ATTR_PERMISSIONS; } win_to_unix_time(stat.ftLastAccessTime, &st->atime); win_to_unix_time(stat.ftLastWriteTime, &st->mtime); *give |= ATTR_ACMODTIME; /* st->acl = NULL; if (want & ATTR_BITS) { st->attrib_bits_valid = ATTR_ARCHIVE | ATTR_COMPRESSED | ATTR_READONLY | ATTR_SYSTEM | ATTR_SPARSE | ATTR_HIDDEN | ATTR_ENCRYPTED; st->attrib_bits = (stat.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) | (stat.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) | (stat.dwFileAttributes & FILE_ATTRIBUTE_READONLY) | (stat.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) | (stat.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) | (stat.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) | (stat.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED); *give |= ATTR_BITS; } */ if (world) FreeSid(world); if (pdesc) LocalFree(pdesc); return FX_OK; }