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