r12608: Remove some unused #include lines.
[ira/wip.git] / source4 / libnet / libnet_samdump.c
1 /* 
2    Unix SMB/CIFS implementation.
3    
4    Extract the user/system database from a remote SamSync server
5
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23
24 #include "includes.h"
25 #include "libnet/libnet.h"
26 #include "dlinklist.h"
27
28
29 struct samdump_secret {
30         struct samdump_secret *prev, *next;
31         DATA_BLOB secret;
32         char *name;
33         NTTIME mtime;
34 };
35
36 struct samdump_trusted_domain {
37         struct samdump_trusted_domain *prev, *next;
38         struct dom_sid *sid;
39         char *name;
40 };
41
42 struct samdump_state {
43         struct samdump_secret *secrets;
44         struct samdump_trusted_domain *trusted_domains;
45 };
46
47 static NTSTATUS vampire_samdump_handle_user(TALLOC_CTX *mem_ctx,
48                                             struct creds_CredentialState *creds,
49                                             struct netr_DELTA_ENUM *delta) 
50 {
51         uint32_t rid = delta->delta_id_union.rid;
52         struct netr_DELTA_USER *user = delta->delta_union.user;
53         const char *username = user->account_name.string;
54         char *hex_lm_password;
55         char *hex_nt_password;
56
57         hex_lm_password = smbpasswd_sethexpwd(mem_ctx, 
58                                               user->lm_password_present ? &user->lmpassword : NULL, 
59                                               user->acct_flags);
60         hex_nt_password = smbpasswd_sethexpwd(mem_ctx, 
61                                               user->nt_password_present ? &user->ntpassword : NULL, 
62                                               user->acct_flags);
63
64         printf("%s:%d:%s:%s:%s:LCT-%08X\n", username,
65                rid, hex_lm_password, hex_nt_password,
66                smbpasswd_encode_acb_info(mem_ctx, user->acct_flags),
67                (unsigned int)nt_time_to_unix(user->last_password_change));
68
69         return NT_STATUS_OK;
70 }
71
72 static NTSTATUS vampire_samdump_handle_secret(TALLOC_CTX *mem_ctx,
73                                               struct samdump_state *samdump_state,
74                                               struct creds_CredentialState *creds,
75                                               struct netr_DELTA_ENUM *delta) 
76 {
77         struct netr_DELTA_SECRET *secret = delta->delta_union.secret;
78         const char *name = delta->delta_id_union.name;
79         struct samdump_secret *new = talloc(samdump_state, struct samdump_secret);
80
81         new->name = talloc_steal(new, name);
82         new->secret = data_blob_talloc(new, secret->current_cipher.cipher_data, secret->current_cipher.maxlen);
83         new->mtime = secret->current_cipher_set_time;
84
85         DLIST_ADD(samdump_state->secrets, new);
86
87         return NT_STATUS_OK;
88 }
89
90 static NTSTATUS vampire_samdump_handle_trusted_domain(TALLOC_CTX *mem_ctx,
91                                               struct samdump_state *samdump_state,
92                                               struct creds_CredentialState *creds,
93                                               struct netr_DELTA_ENUM *delta) 
94 {
95         struct netr_DELTA_TRUSTED_DOMAIN *trusted_domain = delta->delta_union.trusted_domain;
96         struct dom_sid *dom_sid = delta->delta_id_union.sid;
97
98         struct samdump_trusted_domain *new = talloc(samdump_state, struct samdump_trusted_domain);
99
100         new->name = talloc_steal(new, trusted_domain->domain_name.string);
101         new->sid = talloc_steal(new, dom_sid);
102
103         DLIST_ADD(samdump_state->trusted_domains, new);
104
105         return NT_STATUS_OK;
106 }
107
108 static NTSTATUS libnet_samdump_fn(TALLOC_CTX *mem_ctx,          
109                                   void *private,                        
110                                   struct creds_CredentialState *creds,
111                                   enum netr_SamDatabaseID database,
112                                   struct netr_DELTA_ENUM *delta,
113                                   char **error_string)
114 {
115         NTSTATUS nt_status = NT_STATUS_OK;
116         struct samdump_state *samdump_state = private;
117
118         *error_string = NULL;
119         switch (delta->delta_type) {
120         case NETR_DELTA_USER:
121         {
122                 /* not interested in builtin users */
123                 if (database == SAM_DATABASE_DOMAIN) {
124                         nt_status = vampire_samdump_handle_user(mem_ctx, 
125                                                                 creds,
126                                                                 delta);
127                         break;
128                 }
129         }
130         case NETR_DELTA_SECRET:
131         {
132                 nt_status = vampire_samdump_handle_secret(mem_ctx,
133                                                           samdump_state,
134                                                           creds,
135                                                           delta);
136                 break;
137         }
138         case NETR_DELTA_TRUSTED_DOMAIN:
139         {
140                 nt_status = vampire_samdump_handle_trusted_domain(mem_ctx,
141                                                                   samdump_state,
142                                                                   creds,
143                                                                   delta);
144                 break;
145         }
146         default:
147                 /* Can't dump them all right now */
148                 break;
149         }
150         return nt_status;
151 }
152
153 static NTSTATUS libnet_SamDump_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_SamDump *r)
154 {
155         NTSTATUS nt_status;
156         struct libnet_SamSync r2;
157         struct samdump_state *samdump_state = talloc(mem_ctx, struct samdump_state);
158
159         struct samdump_trusted_domain *t;
160         struct samdump_secret *s;
161
162         if (!samdump_state) {
163                 return NT_STATUS_NO_MEMORY;
164         }
165
166         samdump_state->secrets = NULL;
167         samdump_state->trusted_domains = NULL;
168
169         r2.error_string = NULL;
170         r2.delta_fn = libnet_samdump_fn;
171         r2.fn_ctx = samdump_state;
172         r2.machine_account = NULL; /* TODO:  Create a machine account, fill this in, and the delete it */
173         nt_status = libnet_SamSync_netlogon(ctx, samdump_state, &r2);
174         r->error_string = r2.error_string;
175
176         if (!NT_STATUS_IS_OK(nt_status)) {
177                 talloc_free(samdump_state);
178                 return nt_status;
179         }
180
181         printf("Trusted domains, sids and secrets:\n");
182         for (t=samdump_state->trusted_domains; t; t=t->next) {
183                 char *secret_name = talloc_asprintf(mem_ctx, "G$$%s", t->name);
184                 for (s=samdump_state->secrets; s; s=s->next) {
185                         if (strcasecmp_m(s->name, secret_name) == 0) {
186                                 char *secret_string;
187                                 if (convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, 
188                                                           s->secret.data, s->secret.length, 
189                                                           (void **)&secret_string) == -1) {
190                                         r->error_string = talloc_asprintf(mem_ctx, 
191                                                                           "Could not convert secret for domain %s to a string\n",
192                                                                           t->name);
193                                         talloc_free(samdump_state);
194                                         return NT_STATUS_INVALID_PARAMETER;
195                                 }
196                                 printf("%s\t%s\t%s\n", 
197                                        t->name, dom_sid_string(mem_ctx, t->sid), 
198                                        secret_string);
199                         }
200                 }
201         }
202         talloc_free(samdump_state);
203         return nt_status;
204 }
205
206
207
208 static NTSTATUS libnet_SamDump_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_SamDump *r)
209 {
210         NTSTATUS nt_status;
211         struct libnet_SamDump r2;
212         r2.level = LIBNET_SAMDUMP_NETLOGON;
213         r2.error_string = NULL;
214         nt_status = libnet_SamDump(ctx, mem_ctx, &r2);
215         r->error_string = r2.error_string;
216         
217         return nt_status;
218 }
219
220 NTSTATUS libnet_SamDump(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_SamDump *r)
221 {
222         switch (r->level) {
223         case LIBNET_SAMDUMP_GENERIC:
224                 return libnet_SamDump_generic(ctx, mem_ctx, r);
225         case LIBNET_SAMDUMP_NETLOGON:
226                 return libnet_SamDump_netlogon(ctx, mem_ctx, r);
227         }
228
229         return NT_STATUS_INVALID_LEVEL;
230 }