summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in4
-rw-r--r--source3/libsmb/clientgen.c1
-rw-r--r--source3/utils/profiles.c365
3 files changed, 358 insertions, 12 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 589b1a602b..f9a9d0072c 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -646,6 +646,10 @@ bin/net: $(NET_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(NET_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @BUILD_POPT@
+bin/profiles: utils/profiles.o bin/.dummy
+ @echo Linking $@
+ @$(CC) $(FLAGS) -o $@ utils/profiles.o $(LDFLAGS) $(LIBS)
+
bin/smbspool: $(CUPS_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(CUPS_OBJ) $(LDFLAGS) $(LIBS)
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index 28480043b9..fc3cdaffd8 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -175,6 +175,7 @@ void cli_setup_packet(struct cli_state *cli)
if (cli->sign_info.use_smb_signing
|| cli->sign_info.temp_smb_signing)
flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
+ flags2 |= 0xc010;
SSVAL(cli->outbuf,smb_flg2, flags2);
}
}
diff --git a/source3/utils/profiles.c b/source3/utils/profiles.c
index f14bcf8d85..fcf01d71df 100644
--- a/source3/utils/profiles.c
+++ b/source3/utils/profiles.c
@@ -1,3 +1,293 @@
+/*
+ Samba Unix/Linux SMB client utility profiles.c
+ Copyright (C) 2002 Richard Sharpe, rsharpe@richardsharpe.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/*************************************************************************
+
+ A utility to report and change SIDs in registry files
+
+ Many of the ideas in here come from other people and software.
+ I first looked in Wine in misc/registry.c and was also influenced by
+ http://www.wednesday.demon.co.uk/dosreg.html
+
+ Which seems to contain comments from someone else. I reproduce them here
+ incase the site above disappears. It actually comes from
+ http://home.eunet.no/~pnordahl/ntpasswd/WinReg.txt.
+
+The windows NT registry has 2 different blocks, where one can occure many
+times...
+
+the "regf"-Block
+================
+
+"regf" is obviosly the abbreviation for "Registry file". "regf" is the
+signature of the header-block which is always 4kb in size, although only
+the first 64 bytes seem to be used and a checksum is calculated over
+the first 0x200 bytes only!
+
+Offset Size Contents
+0x00000000 D-Word ID: ASCII-"regf" = 0x66676572
+0x00000004 D-Word ???? //see struct REGF
+0x00000008 D-Word ???? Always the same value as at 0x00000004
+0x0000000C Q-Word last modify date in WinNT date-format
+0x00000014 D-Word 1
+0x00000018 D-Word 3
+0x0000001C D-Word 0
+0x00000020 D-Word 1
+0x00000024 D-Word Offset of 1st key record
+0x00000028 D-Word Size of the data-blocks (Filesize-4kb)
+0x0000002C D-Word 1
+0x000001FC D-Word Sum of all D-Words from 0x00000000 to
+0x000001FB //XOR of all words. Nigel
+
+I have analyzed more registry files (from multiple machines running
+NT 4.0 german version) and could not find an explanation for the values
+marked with ???? the rest of the first 4kb page is not important...
+
+the "hbin"-Block
+================
+I don't know what "hbin" stands for, but this block is always a multiple
+of 4kb in size.
+
+Inside these hbin-blocks the different records are placed. The memory-
+management looks like a C-compiler heap management to me...
+
+hbin-Header
+===========
+Offset Size Contents
+0x0000 D-Word ID: ASCII-"hbin" = 0x6E696268
+0x0004 D-Word Offset from the 1st hbin-Block
+0x0008 D-Word Offset to the next hbin-Block
+0x001C D-Word Block-size
+
+The values in 0x0008 and 0x001C should be the same, so I don't know
+if they are correct or swapped...
+
+From offset 0x0020 inside a hbin-block data is stored with the following
+format:
+
+Offset Size Contents
+0x0000 D-Word Data-block size //this size must be a
+multiple of 8. Nigel
+0x0004 ???? Data
+
+If the size field is negative (bit 31 set), the corresponding block
+is free and has a size of -blocksize!
+
+The data is stored as one record per block. Block size is a multiple
+of 4 and the last block reaches the next hbin-block, leaving no room.
+
+Records in the hbin-blocks
+==========================
+
+nk-Record
+
+ The nk-record can be treated as a kombination of tree-record and
+ key-record of the win 95 registry.
+
+lf-Record
+
+ The lf-record is the counterpart to the RGKN-record (the
+ hash-function)
+
+vk-Record
+
+ The vk-record consists information to a single value.
+
+sk-Record
+
+ sk (? Security Key ?) is the ACL of the registry.
+
+Value-Lists
+
+ The value-lists contain information about which values are inside a
+ sub-key and don't have a header.
+
+Datas
+
+ The datas of the registry are (like the value-list) stored without a
+ header.
+
+All offset-values are relative to the first hbin-block and point to the
+block-size field of the record-entry. to get the file offset, you have to add
+the header size (4kb) and the size field (4 bytes)...
+
+the nk-Record
+=============
+Offset Size Contents
+0x0000 Word ID: ASCII-"nk" = 0x6B6E
+0x0002 Word for the root-key: 0x2C, otherwise 0x20 //key symbolic links 0x10. Nigel
+0x0004 Q-Word write-date/time in windows nt notation
+0x0010 D-Word Offset of Owner/Parent key
+0x0014 D-Word number of sub-Keys
+0x001C D-Word Offset of the sub-key lf-Records
+0x0024 D-Word number of values
+0x0028 D-Word Offset of the Value-List
+0x002C D-Word Offset of the sk-Record
+
+0x0030 D-Word Offset of the Class-Name //see NK structure for the use of these fields. Nigel
+0x0044 D-Word Unused (data-trash) //some kind of run time index. Does not appear to be important. Nigel
+0x0048 Word name-length
+0x004A Word class-name length
+0x004C ???? key-name
+
+the Value-List
+==============
+Offset Size Contents
+0x0000 D-Word Offset 1st Value
+0x0004 D-Word Offset 2nd Value
+0x???? D-Word Offset nth Value
+
+To determine the number of values, you have to look at the owner-nk-record!
+
+Der vk-Record
+=============
+Offset Size Contents
+0x0000 Word ID: ASCII-"vk" = 0x6B76
+0x0002 Word name length
+0x0004 D-Word length of the data //if top bit is set when offset contains data. Nigel
+0x0008 D-Word Offset of Data
+0x000C D-Word Type of value
+0x0010 Word Flag
+0x0012 Word Unused (data-trash)
+0x0014 ???? Name
+
+If bit 0 of the flag-word is set, a name is present, otherwise the value has no name (=default)
+
+If the data-size is lower 5, the data-offset value is used to store the data itself!
+
+The data-types
+==============
+Wert Beteutung
+0x0001 RegSZ: character string (in UNICODE!)
+0x0002 ExpandSZ: string with "%var%" expanding (UNICODE!)
+0x0003 RegBin: raw-binary value
+0x0004 RegDWord: Dword
+0x0007 RegMultiSZ: multiple strings, seperated with 0
+ (UNICODE!)
+
+The "lf"-record
+===============
+Offset Size Contents
+0x0000 Word ID: ASCII-"lf" = 0x666C
+0x0002 Word number of keys
+0x0004 ???? Hash-Records
+
+Hash-Record
+===========
+Offset Size Contents
+0x0000 D-Word Offset of corresponding "nk"-Record
+0x0004 D-Word ASCII: the first 4 characters of the key-name, padded with 0's. Case sensitiv!
+
+Keep in mind, that the value at 0x0004 is used for checking the data-consistency! If you change the
+key-name you have to change the hash-value too!
+
+//These hashrecords must be sorted low to high within the lf record. Nigel.
+
+The "sk"-block
+==============
+(due to the complexity of the SAM-info, not clear jet)
+
+Offset Size Contents
+0x0000 Word ID: ASCII-"sk" = 0x6B73
+0x0002 Word Unused
+0x0004 D-Word Offset of previous "sk"-Record
+0x0008 D-Word Offset of next "sk"-Record
+0x000C D-Word usage-counter
+0x0010 D-Word Size of "sk"-record in bytes
+???? //standard self
+relative security desciptor. Nigel
+???? ???? Security and auditing settings...
+????
+
+The usage counter counts the number of references to this
+"sk"-record. You can use one "sk"-record for the entire registry!
+
+Windows nt date/time format
+===========================
+The time-format is a 64-bit integer which is incremented every
+0,0000001 seconds by 1 (I don't know how accurate it realy is!)
+It starts with 0 at the 1st of january 1601 0:00! All values are
+stored in GMT time! The time-zone is important to get the real
+time!
+
+Common values for win95 and win-nt
+==================================
+Offset values marking an "end of list", are either 0 or -1 (0xFFFFFFFF).
+If a value has no name (length=0, flag(bit 0)=0), it is treated as the
+"Default" entry...
+If a value has no data (length=0), it is displayed as empty.
+
+simplyfied win-3.?? registry:
+=============================
+
++-----------+
+| next rec. |---+ +----->+------------+
+| first sub | | | | Usage cnt. |
+| name | | +-->+------------+ | | length |
+| value | | | | next rec. | | | text |------->+-------+
++-----------+ | | | name rec. |--+ +------------+ | xxxxx |
+ +------------+ | | value rec. |-------->+------------+ +-------+
+ v | +------------+ | Usage cnt. |
++-----------+ | | length |
+| next rec. | | | text |------->+-------+
+| first sub |------+ +------------+ | xxxxx |
+| name | +-------+
+| value |
++-----------+
+
+Greatly simplyfied structure of the nt-registry:
+================================================
+
++---------------------------------------------------------------+
+| |
+v |
++---------+ +---------->+-----------+ +----->+---------+ |
+| "nk" | | | lf-rec. | | | nk-rec. | |
+| ID | | | # of keys | | | parent |---+
+| Date | | | 1st key |--+ | .... |
+| parent | | +-----------+ +---------+
+| suk-keys|-----+
+| values |--------------------->+----------+
+| SK-rec. |---------------+ | 1. value |--> +----------+
+| class |--+ | +----------+ | vk-rec. |
++---------+ | | | .... |
+ v | | data |--> +-------+
+ +------------+ | +----------+ | xxxxx |
+ | Class name | | +-------+
+ +------------+ |
+ v
+ +---------+ +---------+
+ +----->| next sk |--->| Next sk |--+
+ | +---| prev sk |<---| prev sk | |
+ | | | .... | | ... | |
+ | | +---------+ +---------+ |
+ | | ^ | |
+ | +----------+ |
+ +-------------------------------+
+
+---------------------------------------------------------------------------
+
+Hope this helps.... (Although it was "fun" for me to uncover this things,
+ it took me several sleepless nights ;)
+
+ B.D.
+
+*************************************************************************/
#include "includes.h"
#include <stdio.h>
#include <errno.h>
@@ -101,6 +391,36 @@ typedef struct acl_struct {
#define OFF(f) (0x1000 + (f) + 4)
+/* Compare two SIDs for equality */
+int compare_sid(DOM_SID *s1, DOM_SID *s2)
+{
+ int sa1, sa2;
+
+ if (s1->sid_rev_num != s2->sid_rev_num) return 0;
+
+ sa1 = s1->num_auths; sa2 = s2->num_auths;
+
+ if (sa1 != sa2) return 0;
+
+ return !bcmp((char *)&s1->id_auth, (char *)&s2->id_auth,
+ 6 + sa1 * 4);
+
+}
+
+/*
+ * Replace SID1, component by component with SID2
+ * Assumes will never be called with unequal length SIDS
+ * so only touches 21-x-y-z-rid portion
+ */
+void change_sid(DOM_SID *s1, DOM_SID *s2)
+{
+ int i;
+
+ for (i=0; i<s1->num_auths; i++) {
+ s1->sub_auths[i] = s2->sub_auths[i];
+ }
+}
+
void print_sid(DOM_SID *sid)
{
int i, comps = sid->num_auths;
@@ -120,7 +440,7 @@ void print_acl(ACL *acl, char *prefix)
ACE *ace;
ace_cnt = acl->num_aces;
- ace = &acl->aces;
+ ace = (ACE *)&acl->aces;
fprintf(stdout, "%sACEs: %u\n", prefix, ace_cnt);
for (i=0; i<ace_cnt; i++) {
fprintf(stdout, "%s Perms: %08X, SID: ", prefix, ace->perms);
@@ -129,9 +449,23 @@ void print_acl(ACL *acl, char *prefix)
}
}
+void usage(voi)
+{
+ fprintf(stderr, "usage: profiles [-c <OLD-SID> -n <NEW-SID>] <profilefile>\n");
+ fprintf(stderr, "Version: %s\n", VERSION);
+ fprintf(stderr, "\n\t-c S-1-5-21-z-y-x-oldrid provides SID to change");
+ fprintf(stderr, "\n\t-n S-1-5-21-a-b-c-newrid provides SID to change to");
+ fprintf(stderr, "\n\t\tBoth must be present if the other is.");
+ fprintf(stderr, "\n\t\tIf neither present, just report the SIDs found\n");
+}
+
+DOM_SID old_sid, new_sid;
+
int main(int argc, char *argv[])
{
int i, fd, aces, start = 0;
+ int verbose = 0;
+ int process_sids = 0;
void *base;
struct stat sbuf;
fstring sid_str;
@@ -144,10 +478,14 @@ int main(int argc, char *argv[])
int *ptr;
if (argc < 2) {
- fprintf(stderr, "Usage: profiles profile-file\n");
+ usage();
exit(1);
}
+ /*
+ * Now, process the arguments
+ */
+
fd = open(argv[1], O_RDWR, 0000);
if (fd < 0) {
@@ -177,15 +515,15 @@ int main(int argc, char *argv[])
regf_hdr = (REGF_HDR *)base;
- fprintf(stdout, "Registry file size: %u\n", sbuf.st_size);
+ if (verbose) fprintf(stdout, "Registry file size: %u\n", sbuf.st_size);
if (regf_hdr->REGF_ID != REG_REGF_ID) {
fprintf(stderr, "Incorrect Registry file (doesn't have header ID): %s\n", argv[1]);
exit(5);
}
- fprintf(stdout, "First Key Off: %u, Data Block Size: %u\n",
- regf_hdr->first_key, regf_hdr->dblk_size);
+ if (verbose) fprintf(stdout, "First Key Off: %u, Data Block Size: %u\n",
+ regf_hdr->first_key, regf_hdr->dblk_size);
hbin_hdr = (HBIN_HDR *)(base + 0x1000);
@@ -198,8 +536,8 @@ int main(int argc, char *argv[])
exit(6);
}
- fprintf(stdout, "Next Off: %u, Prev Off: %u\n",
- hbin_hdr->next_off, hbin_hdr->prev_off);
+ if (verbose) fprintf(stdout, "Next Off: %u, Prev Off: %u\n",
+ hbin_hdr->next_off, hbin_hdr->prev_off);
nk_hdr = (NK_HDR *)(base + 0x1000 + regf_hdr->first_key + 4);
@@ -208,8 +546,10 @@ int main(int argc, char *argv[])
exit(7);
}
- fprintf(stdout, "Type: %0x\n", nk_hdr->type);
- fprintf(stdout, "SK Off : %o\n", (0x1000 + nk_hdr->sk_off + 4));
+ if (verbose) {
+ fprintf(stdout, "Type: %0x\n", nk_hdr->type);
+ fprintf(stdout, "SK Off : %o\n", (0x1000 + nk_hdr->sk_off + 4));
+ }
sk_hdr = (SK_HDR *)(base + 0x1000 + nk_hdr->sk_off + 4);
sk_off = first_sk_off = nk_hdr->sk_off;
@@ -223,9 +563,10 @@ int main(int argc, char *argv[])
exit(8);
}
ptr = (int *)sk_hdr;
- fprintf(stdout, "Off: %08X, Refs: %u, Size: %u\n",
- sk_off, sk_hdr->ref_cnt, sk_hdr->rec_size);
- sec_desc = &(sk_hdr->sec_desc[0]);
+ if (verbose) fprintf(stdout, "Off: %08X, Refs: %u, Size: %u\n",
+ sk_off, sk_hdr->ref_cnt, sk_hdr->rec_size);
+
+ sec_desc = (MY_SEC_DESC *)&(sk_hdr->sec_desc[0]);
owner_sid = (DOM_SID *)(&sk_hdr->sec_desc[0] + sec_desc->owner_off);
group_sid = (DOM_SID *)(&sk_hdr->sec_desc[0] + sec_desc->group_off);
sacl = (ACL *)(&sk_hdr->sec_desc[0] + sec_desc->sacl_off);