The code for inspecting the SECDESC in NTUSER.DAT

Richard Sharpe rsharpe at
Wed Oct 30 08:09:00 GMT 2002


Attached is the code if anyone wants to play with it.

A little more work and we might be able to modify the two SIDs that need 
changing if the Domain SID changes out from under a user.
The link line is:

 gcc -I../include -I../ubiqx -I../nsswitch -I../smbwrapper -I.. -o \ 
profiles profiles.c

Richard Sharpe, rsharpe at, rsharpe at, 
sharpe at,
-------------- next part --------------
#include "includes.h"
#include <stdio.h>
#include <errno.h>

print_sid(DOM_SID *sid)
  int i, comps = sid->num_auths;
  fprintf(stdout, "S-%u-%u", sid->sid_rev_num, sid->id_auth[5]);

  for (i = 0; i < comps; i++) {

    fprintf(stdout, "-%u", sid->sub_auths[i]);

  fprintf(stdout, "\n");

int main(int argc, char *argv[])
  int i, fd, aces;
  typedef struct profiles_secdesc {
    unsigned char type;
    unsigned char flags;
    unsigned short length;
    unsigned int perms;
    DOM_SID trustee;
  MY_SECDESC *sec_desc;
  char buf[512];
  fstring sid_str;

  if (argc < 2) {
    fprintf(stderr, "Usage: profiles profile-file\n");

  fd = open(argv[1], O_RDONLY, 0000);

  if (fd < 0) {
    fprintf(stderr, "Could not open %s: %s\n", argv[1], 

  lseek(fd, 4272, SEEK_SET);  /* This is where the SECDESC is */

  if (read(fd, buf, sizeof(buf)) < sizeof(buf)) {
    fprintf(stderr, "Could not read enough bytes ...\n");

   * Now, decipher it ...

   aces = (int *)buf[0];
   fprintf(stdout, "Number of ACEs: %ud\n", aces);

   sec_desc = &buf[4];

   for (i = 0; i < aces; i++) {
     fprintf(stdout, "Type: %02X, Flags: %02X, Len: %u, Perms: %08X\n",
		     sec_desc->type, sec_desc->flags, sec_desc->length,

     sec_desc = (char *)sec_desc + sec_desc->length;

More information about the samba-technical mailing list