-
Notifications
You must be signed in to change notification settings - Fork 5
/
sam.h
296 lines (224 loc) · 9.78 KB
/
sam.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
/*
* sam.h - known structures in the SAM hive of NT registry
*
*****
*
* NTREG - Window registry file reader / writer library
* Copyright (c) 1997-2012 Petter Nordahl-Hagen.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library 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
* Lesser General Public License for more details.
* See file LGPL.txt for the full license.
*
*/
#ifndef _INCLUDE_SAM_H
#define _INCLUDE_SAM_H 1
#include <sys/types.h>
#include <inttypes.h>
/* Account V, contains machine SID and a lot of unknonw stuff */
#define SID_BIN_LEN 24 /* Lenght of binary machine SID, incl header */
#define SID_STR_MAX 50 /* Max string lenght of S-1-5-xxx-xxx-xxx-xxx type SID */
#define ACCOUNTDB_V_PATH "\\SAM\\Domains\\Account\\V"
struct accountdb_V {
char unknown1[0x38]; /* No idea what it does */
uint32_t sid_ofs; /* 38 - Offset to machine SID */
uint32_t sid_len; /* 3c - Lenght of sid (should be 0x14?) */
// char unknown2[0x4]; /* 40 */
/* Data start at 0x40 ?? */
char data[4];
};
/* This contains some policy settings for the account database */
#define ACCOUNTDB_F_PATH "\\SAM\\Domains\\Account\\F"
struct accountdb_F {
char unknown1[8]; /* 0 */
char unknown2[8]; /* 8 */
uint32_t updatecnt; /* 10 Number of times policy data updated */
char unknown3[4]; /* 14 */
char t_maxpwage[8]; /* 18 Maximum password age, GUI shows only days */
char t_minpwage[8]; /* 20 Minimum password age, GUI shows only days */
char unknown4[8]; /* 28 */
char t_lockdur[8]; /* 30 Account lockout duration, GUI shows minutes */
char t_lockrel[8]; /* 38 Release account lockout after, GUI show minutes */
char unknown5[8]; /* 40 */
uint32_t rid; /* 48 RID of user doing last edit? */
uint32_t flags; /* 4c Some flags & options, see below */
unsigned short minpwlen; /* 50 Minimum password lenght */
unsigned short numhist; /* 52 How many passwords to keep in history */
unsigned short locklimit; /*54 How many tries before lockout */
char unknown6[0x9a]; /* Rest is unknown */
}; /* Total size 0xF0 bytes, seems to be constant */
/* Known bits in flags field */
#define ACF_COMPLEX 0x0001 /* Pass must meet complexity req. */
#define ACF_REVERSIBLE 0x0010 /* Store password using reversible encryption */
/* This is users F value, contains account type & state etc */
#define USER_F_PATH "\\SAM\\Domains\\Account\\Users\\%08X\\F"
struct user_F {
char unknown1[8];
char t_lockout[8]; /* Time of lockout */
char unknown2[8];
char t_creation[8]; /* Time of account creation */
char unknown3[8];
char t_login[8]; /* Time of last login */
int32_t rid;
char unknown4[4];
unsigned short ACB_bits; /* Account type and status flags */
char unknown5[6];
unsigned short failedcnt; /* Count of failed logins, if > than policy it is locked */
unsigned short logins; /* Total logins since creation */
char unknown6 [0xc];
};
#define ACB_DISABLED 0x0001 /* Act disabled */
#define ACB_HOMDIRREQ 0x0002 /* Home directory required */
#define ACB_PWNOTREQ 0x0004 /* User password not req */
#define ACB_TEMPDUP 0x0008 /* Temporary duplicate account?? */
#define ACB_NORMAL 0x0010 /* Normal user account */
#define ACB_MNS 0x0020 /* MNS logon user account */
#define ACB_DOMTRUST 0x0040 /* Interdomain trust account */
#define ACB_WSTRUST 0x0080 /* Workstation trust account */
#define ACB_SVRTRUST 0x0100 /* Server trust account */
#define ACB_PWNOEXP 0x0200 /* User password does not expire */
/* Seems not to be used on failed console logins at least */
#define ACB_AUTOLOCK 0x0400 /* Account auto locked */
/* Account Bits Fields strings (defined in libsam.c)
char *acb_fields[16] = {
"Disabled" ,
"Homedir req." ,
"Passwd not req." ,
"Temp. duplicate" ,
"Normal account" ,
"NMS account" ,
"Domain trust act." ,
"Wks trust act." ,
"Srv trust act" ,
"Pwd don't expire" ,
"Auto lockout" ,
"(unknown 0x08)" ,
"(unknown 0x10)" ,
"(unknown 0x20)" ,
"(unknown 0x40)" ,
"(unknown 0x80)" ,
};
*/
/* Users V data struct */
/* First 0xCC bytes is pointer & len table, rest is data which
* the table points to
* String data is unicode, not zero terminated (must use len)
*/
struct user_V {
int unknown1_1; /* 0x00 - always zero? */
int unknown1_2; /* 0x04 - points to username? */
int unknown1_3; /* 0x08 - always 0x02 0x00 0x01 0x00 ? */
int username_ofs; /* 0x0c */
int username_len; /* 0x10 */
int unknown2_1; /* 0x14 - always zero? */
int fullname_ofs; /* 0x18 */
int fullname_len; /* 0x1c */
int unknown3_1; /* 0x20 - always zero? */
int comment_ofs; /* 0x24 */
int comment_len; /* 0x28 */
int unknown4_1; /* 0x2c - alway zero? */
int unknown4_2; /* 0x30 - points 4 or 8 byte field before hashes */
int unknown4_3; /* 0x34 - zero? or size? */
int unknown4_4; /* 0x38 - zero? */
int unknown4_5; /* 0x3c - to field 8 bytes before hashes */
int unknown4_6; /* 0x40 - zero? or size of above? */
int unknown4_7; /* 0x44 - zero? */
int homedir_ofs; /* 0x48 */
int homedir_len; /* 0x4c */
int unknown5_1; /* 0x50 - zero? */
int drvletter_ofs; /* 0x54 - drive letter for home dir */
int drvletter_len; /* 0x58 - len of above, usually 4 */
int unknown6_1; /* 0x5c - zero? */
int logonscr_ofs; /* 0x60 - users logon script path */
int logonscr_len; /* 0x64 - length of string */
int unknown7_1; /* 0x68 - zero? */
int profilep_ofs; /* 0x6c - profile path string */
int profilep_len; /* 0x70 - profile path stringlen */
char unknown7[0x90-0x74]; /* 0x74 */
int unknown8_1; /* 0x90 - pointer to some place before hashes, after comments */
int unknown8_2; /* 0x94 - size of above? */
int unknown8_3; /* 0x98 - unknown? always 1? */
int lmpw_ofs; /* 0x9c */
int lmpw_len; /* 0xa0 */
int unknown9_1; /* 0xa4 - zero? */
int ntpw_ofs; /* 0xa8 */
int ntpw_len; /* 0xac */
int unknowna_1; /* 0xb0 */
int unknowna_2; /* 0xb4 - points to field after hashes */
int unknowna_3; /* 0xb8 - size of above field */
int unknowna_4; /* 0xbc - zero? */
int unknowna_5; /* 0xc0 - points to field after that */
int unknowna_6; /* 0xc4 - size of above */
int unknowna_7; /* 0xc8 - zero ? */
char data[4]; /* Data starts here. All pointers above is relative to this,
that is V + 0xCC */
};
/* Groups C data struct
* First 0x34 bytes is pointer & len table, rest is data which
* the table points to
* String data is unicode, not zero terminated (must use len)
*/
struct group_C {
int groupid; /* 0x00 - Seems to be the group ID */
int unknown1_1; /* 0x04 - always zero? */
int unknown1_2; /* 0x08 - points to groupname? */
int unknown1_3; /* 0x0c - always 0x02 0x00 0x01 0x00 ? */
int grpname_ofs; /* 0x10 */
int grpname_len; /* 0x14 */
int unknown2_1; /* 0x18 - always zero? */
int fullname_ofs; /* 0x1c */
int fullname_len; /* 0x20 */
int unknown3_1; /* 0x24 - always zero? */
int members_ofs; /* 0x28 - offset to member list, which is SIDs */
int members_len; /* 0x2c - member list size */
int grp_members; /* 0x30 - number of group members */
/* 0x34 - data starts here. pointers above are offset from this */
char data[];
};
/* Variable length binary structure that most SIDs are stored in
*/
struct sid_binary {
uint8_t revision; /* 0x0 - Don't know. Always 1? Revision level? number of SIDs following? */
uint8_t sections; /* 0x1 - Number of parts, 4 bytes each (unsigne integer) */
uint8_t unknown2; /* 0x2 - Unknown, seems to be null padding */
uint8_t unknown3; /* 0x3 - Unknown, seems to be null padding */
uint8_t unknown4; /* 0x4 - Unknown */
uint8_t unknown5; /* 0x5 - Unknown */
uint8_t unknown6; /* 0x6 - Unknown */
uint8_t authority; /* 0x7 - Unknown, often 5 (could this be 8bit authority number?) */
uint32_t array[8]; /* As many as sections value says it is */
};
/* Array of SIDs */
struct sid_array {
int len;
struct sid_binary *sidptr;
};
/* libsam.c functions */
int sam_get_lockoutinfo(struct hive *hdesc, int show);
short sam_handle_accountbits(struct hive *hdesc, int rid, int mode);
int sam_get_machine_sid(struct hive *hdesc, char *sidbuf);
char *sam_sid_to_string(struct sid_binary *sidbuf);
struct sid_array *sam_make_sid_array(struct sid_binary *sidbuf, int size);
void sam_free_sid_array(struct sid_array *array);
int sam_sid_cmp(struct sid_binary *s1, struct sid_binary *s2);
int sam_get_grp_members_sid(struct hive *hdesc, int grp, struct sid_array **sarray);
int sam_put_grp_members_sid(struct hive *hdesc, int grp, struct sid_array *sarray);
struct keyval *sam_get_user_grpids(struct hive *hdesc, int rid);
int sam_put_user_grpids(struct hive *hdesc, int rid, struct keyval *val);
int sam_add_user_to_grp(struct hive *hdesc, int rid, int grp);
int sam_remove_user_from_grp(struct hive *hdesc, int rid, int grp);
char *sam_get_username(struct hive *hdesc, int rid);
char *sam_get_groupname(struct hive *hdesc, int grpid);
int sam_list_users(struct hive *hdesc, int readable);
int sam_list_user_groups(struct hive *hdesc, int rid, int check);
int sam_reset_pw(struct hive *hdesc, int rid);
void sam_list_groups(struct hive *hdesc, int listmembers, int human);
int sam_reset_all_pw(struct hive *hdesc, int list);
#endif