Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
Hello all,

This is a rant with supporting code illustrating the amount of work it takes to change the owner of a file on Windows and on Linux. If you don't want to hear me bitch, skip the rest of this node. If you really don't want to hear it, vote this node down and I'll take the hint. :)

I sent this email to the other (primarily Linux Perl) developers in my company. I thought I'd post it here so all can partake of the schadenfreude:

Here's how you change a file owner in Windows (for which you have to use C):

// #includes omitted for the sake of sanity HANDLE token; char *filename = "somefile.txt"; char *newuser = "someuser"; DWORD len; PSECURITY_DESCRIPTOR security = NULL; PSID sidPtr = NULL; int retValue = 1; // Get the privileges you need if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILE +GES, &token)) { SetPrivilege(token, "SeTakeOwnershipPrivilege", 1); SetPrivilege(token, "SeSecurityPrivilege", 1); SetPrivilege(token, "SeBackupPrivilege", 1); SetPrivilege(token, "SeRestorePrivilege", 1); } else retValue = 0; // Create the security descriptor if (retValue) { GetFileSecurity(filename, OWNER_SECURITY_INFORMATION, secu +rity, 0, &len); security = (PSECURITY_DESCRIPTOR)malloc(len); if (!InitializeSecurityDescriptor(security, SECURITY_DESCRIPTOR_REVISION)) retValue = 0; } // Get the sid for the username if (retValue) { char domainbuf[4096]; DWORD sidSize = 0; DWORD bufSize = 4096; SID_NAME_USE sidUse; LookupAccountName(NULL, newuser, sidPtr, &sidSize, domainb +uf, &bufSize, &sidUse); sid = (PSID)malloc(sidSize); if (!LookupAccountName(NULL, string, (PSID)sid, &sidSize, +domainbuf, &bufSize, &sidUse)) retValue = 0; } } // Set the sid to be the new owner if (retValue && !SetSecurityDescriptorOwner(security, sidPtr, +0)) retValue = 0; // Save the security descriptor if (retValue) retValue = SetFileSecurity(filename, OWNER_SECURITY_INFORM +ATION, security); if (security) free(security); if (sid) free(sid); return retValue;
Here's how you do it on Linux (for which you can use perl):
my $filename = 'somefile'; my $newuser = 'someuser'; my $newuid = getpwname($newuser)[2]; my $oldguid = stat($filename)[5]; return ($newuid && chown($newuid, $oldguid, $filename));
Of course, you could do the Linux in one fairly readable line, if you were so inclined...
my $filename = 'somefile'; my $newuser = 'someuser'; return getpwname($newuser) && chown(getpwnam($newuser)[2], sta +t($filename)[5], $filename);
Some of the code bloat comes from the poorly designed API, and some comes from the memory management you have to do in C. Note also that this procedure is very poorly documented; I had to pick through dozens of code fragments, Microsoft help files, and newgroup entries to get this. I got the perl code in a couple minutes from the camel head book.

The upshot? C takes a long time to develop in and sucks for some things (feel free to show these pieces of code the next time someone asks why C takes longer to develop in than Perl). And Microsoft just plain sucks.


btw: I am aware that there is a Win32::Perms module available that does this. Sadly, the Perms module fails at setting access control lists. I therefore had to write my own, and figured I should have my module do the owner/group stuff as well.

In reply to Changing owner of files: Windows vs Linux (or Why I hate Windows) by ton

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others musing on the Monastery: (5)
    As of 2020-02-21 17:09 GMT
    Find Nodes?
      Voting Booth?
      What numbers are you going to focus on primarily in 2020?

      Results (96 votes). Check out past polls.