show builtin groups in samdump
[tprouty/samba.git] / source3 / utils / net_rpc_samsync.c
1 /* 
2    Unix SMB/CIFS implementation.
3    dump the remote SAM using rpc samsync operations
4
5    Copyright (C) Andrew Tridgell 2002
6    Copyright (C) Tim Potter 2001,2002
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 #include "includes.h"
24 #include "../utils/net.h"
25
26 static void display_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *g)
27 {
28         int i;
29         d_printf("Group mem %u: ", rid);
30         for (i=0;i<g->num_members;i++) {
31                 d_printf("%u ", g->rids[i]);
32         }
33         d_printf("\n");
34 }
35
36 static void display_alias_info(uint32 rid, SAM_ALIAS_INFO *a)
37 {
38         d_printf("Alias '%s' ", unistr2_static(&a->uni_als_name));
39         d_printf("desc='%s' rid=%u\n", unistr2_static(&a->uni_als_desc), a->als_rid);
40 }
41
42 static void display_alias_mem(uint32 rid, SAM_ALIAS_MEM_INFO *a)
43 {
44         int i;
45         d_printf("Alias rid %u: ", rid);
46         for (i=0;i<a->num_members;i++) {
47                 d_printf("%s ", sid_string_static(&a->sids[i].sid));
48         }
49         d_printf("\n");
50 }
51
52 static void display_account_info(uint32 rid, SAM_ACCOUNT_INFO *a)
53 {
54         fstring hex_nt_passwd, hex_lm_passwd;
55         uchar lm_passwd[16], nt_passwd[16];
56
57         /* Decode hashes from password hash */
58         sam_pwd_hash(a->user_rid, a->pass.buf_lm_pwd, lm_passwd, 0);
59         sam_pwd_hash(a->user_rid, a->pass.buf_nt_pwd, nt_passwd, 0);
60         
61         /* Encode as strings */
62         smbpasswd_sethexpwd(hex_lm_passwd, lm_passwd, a->acb_info);
63         smbpasswd_sethexpwd(hex_nt_passwd, nt_passwd, a->acb_info);
64         
65         printf("%s:%d:%s:%s:%s:LCT-0\n", unistr2_static(&a->uni_acct_name),
66                a->user_rid, hex_lm_passwd, hex_nt_passwd,
67                smbpasswd_encode_acb_info(a->acb_info));
68 }
69
70 static void display_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta)
71 {
72         switch (hdr_delta->type) {
73         case SAM_DELTA_ACCOUNT_INFO:
74                 display_account_info(hdr_delta->target_rid, &delta->account_info);
75                 break;
76         case SAM_DELTA_GROUP_MEM:
77                 display_group_mem_info(hdr_delta->target_rid, &delta->grp_mem_info);
78                 break;
79         case SAM_DELTA_ALIAS_INFO:
80                 display_alias_info(hdr_delta->target_rid, &delta->alias_info);
81                 break;
82         case SAM_DELTA_ALIAS_MEM:
83                 display_alias_mem(hdr_delta->target_rid, &delta->als_mem_info);
84                 break;
85         default:
86                 d_printf("Unknown delta record type %d\n", hdr_delta->type);
87                 break;
88         }
89 }
90
91
92 static void dump_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds)
93 {
94         unsigned last_rid = 0;
95         NTSTATUS result;
96         int i;
97         TALLOC_CTX *mem_ctx;
98         SAM_DELTA_HDR *hdr_deltas;
99         SAM_DELTA_CTR *deltas;
100         uint32 num_deltas;
101
102         if (!(mem_ctx = talloc_init())) {
103                 return;
104         }
105
106         d_printf("Dumping database %u\n", db_type);
107
108         do {
109                 result = cli_netlogon_sam_sync(cli, mem_ctx, ret_creds, db_type, last_rid+1,
110                                                &num_deltas, &hdr_deltas, &deltas);
111                 clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), ret_creds);
112                 last_rid = 0;
113                 for (i = 0; i < num_deltas; i++) {
114                         display_sam_entry(&hdr_deltas[i], &deltas[i]);
115                         last_rid = hdr_deltas[i].target_rid;
116                         if (last_rid == 0) {
117                                 break;
118                         }
119                 }
120         } while (last_rid && NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
121
122         talloc_destroy(mem_ctx);
123 }
124
125 /* dump sam database via samsync rpc calls */
126 int rpc_samdump(int argc, const char **argv)
127 {
128         NTSTATUS result;
129         struct cli_state *cli = NULL;
130         uchar trust_password[16];
131         DOM_CRED ret_creds;
132
133         ZERO_STRUCT(ret_creds);
134
135         /* Connect to remote machine */
136         if (!(cli = net_make_ipc_connection(NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC))) {
137                 return 1;
138         }
139
140         if (!cli_nt_session_open(cli, PIPE_NETLOGON)) {
141                 DEBUG(0,("Error connecting to NETLOGON pipe\n"));
142                 goto fail;
143         }
144
145         if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_password, NULL)) {
146                 d_printf("Could not retrieve domain trust secret");
147                 goto fail;
148         }
149         
150         result = cli_nt_setup_creds(cli, SEC_CHAN_BDC,  trust_password);
151         if (!NT_STATUS_IS_OK(result)) {
152                 d_printf("Failed to setup BDC creds\n");
153                 goto fail;
154         }
155
156         dump_database(cli, SAM_DATABASE_DOMAIN, &ret_creds);
157         dump_database(cli, SAM_DATABASE_BUILTIN, &ret_creds);
158         dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds);
159
160         cli_nt_session_close(cli);
161         
162         return 0;
163
164 fail:
165         if (cli) {
166                 cli_nt_session_close(cli);
167         }
168         return -1;
169 }