summaryrefslogtreecommitdiff
path: root/examples/libmsrpc/test/lsa/ear.c
blob: 8a8202543daeaa32d2033e508beeae57031dfc58 (plain)
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
/* connects to an LSA, asks for a list of server names,  prints out their sids, then looks up their names from the sids and prints them out again
 *  if you run as lsaq -p, then it will simulate a partial success for cac_GetNamesFromSids. It will try to lookup the server's local and domain sids
 */


#include "libmsrpc.h"
#include "includes.h"

void fill_conn_info(CacServerHandle *hnd) {
   pstring domain;
   pstring username;
   pstring password;
   pstring server;

   fprintf(stdout, "Enter domain name: ");
   fscanf(stdin, "%s", domain);

   fprintf(stdout, "Enter username: ");
   fscanf(stdin, "%s", username);

   fprintf(stdout, "Enter password (no input masking): ");
   fscanf(stdin, "%s", password);

   fprintf(stdout, "Enter server (ip or name): ");
   fscanf(stdin, "%s", server);

   hnd->domain = SMB_STRDUP(domain);
   hnd->username = SMB_STRDUP(username);
   hnd->password = SMB_STRDUP(password);
   hnd->server = SMB_STRDUP(server);
}

void get_server_names(TALLOC_CTX *mem_ctx, int *num_names, char ***names) {
   int i = 0;
   pstring tmp;
   
   fprintf(stdout, "How many names do you want to lookup?: ");
   fscanf(stdin, "%d", num_names);

   *names = TALLOC_ARRAY(mem_ctx, char *, *num_names);
   if(*names == NULL) {
      fprintf(stderr, "No memory for allocation\n");
      exit(-1);
   }

   for(i = 0; i < *num_names; i++) {
      fprintf(stdout, "Enter name: ");
      fscanf(stdin, "%s", tmp);
      (*names)[i] = talloc_strdup(mem_ctx, tmp);
   }
}

int main(int argc, char **argv) {
   int i;
   int result;
   char **names;
   int num_names;
   int num_sids;
   CacServerHandle *hnd = NULL;
   POLICY_HND *lsa_pol  = NULL;
   TALLOC_CTX *mem_ctx  = NULL;

   DOM_SID *sid_buf     = NULL;

   BOOL sim_partial     = False;

   if(argc > 1 && strcmp(argv[1], "-p") == 0)
      sim_partial = True;

   mem_ctx = talloc_init("lsaq");

   hnd = cac_NewServerHandle(False);

   fill_conn_info(hnd);

   get_server_names(mem_ctx, &num_names, &names);

   /*connect to the PDC and open a LSA handle*/
   if(!cac_Connect(hnd, NULL)) {
      fprintf(stderr, "Could not connect to server.\n Error %s.\n", nt_errstr(hnd->status));
      cac_FreeHandle(hnd);
      exit(-1);
   }

   fprintf(stdout, "Connected to server: %s\n", hnd->server);

   struct LsaOpenPolicy lop;
   ZERO_STRUCT(lop);

   lop.in.access = SEC_RIGHT_MAXIMUM_ALLOWED;
   lop.in.security_qos = True;

   if(!cac_LsaOpenPolicy(hnd, mem_ctx, &lop)) {
      fprintf(stderr, "Could not get lsa policy handle.\n Error: %s\n", nt_errstr(hnd->status));
      cac_FreeHandle(hnd);
      exit(-1);
   }

   fprintf(stdout, "Opened Policy Handle\n");

   /*just to make things neater*/
   lsa_pol = lop.out.pol;

   /*fetch the local sid and domain sid for the pdc*/

   struct LsaFetchSid fsop;
   ZERO_STRUCT(fsop);

   fsop.in.pol = lsa_pol;
   fsop.in.info_class = (CAC_LOCAL_INFO|CAC_DOMAIN_INFO);

   fprintf(stdout, "fetching SID info for %s\n", hnd->server);

   result = cac_LsaFetchSid(hnd, mem_ctx, &fsop);
   if(!result) {
      fprintf(stderr, "Could not get sid for server: %s\n. Error: %s\n", hnd->server, nt_errstr(hnd->status));
      cac_FreeHandle(hnd);
      talloc_destroy(mem_ctx);
      exit(-1);
   }

   if(result == CAC_PARTIAL_SUCCESS) {
      fprintf(stdout, "could not retrieve both domain and local information\n");
   }
   

   fprintf(stdout, "Fetched SID info for %s\n", hnd->server);
   if(fsop.out.local_sid != NULL)
      fprintf(stdout, " domain: %s. Local SID: %s\n", fsop.out.local_sid->domain, sid_string_static(&fsop.out.local_sid->sid));

   if(fsop.out.domain_sid != NULL)
      fprintf(stdout, " domain: %s, Domain SID: %s\n", fsop.out.domain_sid->domain, sid_string_static(&fsop.out.domain_sid->sid));

   fprintf(stdout, "Looking up sids\n");

   
   struct LsaGetSidsFromNames gsop;
   ZERO_STRUCT(gsop);
   
   gsop.in.pol       = lsa_pol;
   gsop.in.num_names = num_names;
   gsop.in.names     = names;

   result = cac_LsaGetSidsFromNames(hnd, mem_ctx, &gsop);

   if(!result) {
      fprintf(stderr, "Could not lookup any sids!\n Error: %s\n", nt_errstr(hnd->status));
      goto done;
   }

   if(result == CAC_PARTIAL_SUCCESS) {
      fprintf(stdout, "Not all names could be looked up.\nThe following names were not found:\n");
      
      for(i = 0; i < (num_names - gsop.out.num_found); i++) {
         fprintf(stdout, " %s\n", gsop.out.unknown[i]);
      }
      
      fprintf(stdout, "\n");
   }

   /*buffer the sids so we can look them up back to names*/
   num_sids = (sim_partial) ? gsop.out.num_found + 2: gsop.out.num_found;
   sid_buf = TALLOC_ARRAY(mem_ctx, DOM_SID, num_sids);

   fprintf(stdout, "%d names were resolved: \n", gsop.out.num_found);


   i = 0;
   while(i < gsop.out.num_found) {
      fprintf(stdout, " Name: %s\n SID: %s\n\n", gsop.out.sids[i].name, sid_string_static(&gsop.out.sids[i].sid));

      sid_buf[i] = gsop.out.sids[i].sid;

      printf("Attempting to open account\n");

      struct LsaOpenAccount loa;
      ZERO_STRUCT(loa);

      loa.in.pol    = lsa_pol;
      loa.in.access = SEC_RIGHT_MAXIMUM_ALLOWED;
      loa.in.sid    = &gsop.out.sids[i].sid;

      if(!cac_LsaOpenAccount(hnd, mem_ctx, &loa)) {
         fprintf(stderr, "Could not open account.\n Error: %s\n", nt_errstr(hnd->status));
      }

      printf("\nEnumerating privs:");
      struct LsaEnumAccountRights earop;
      ZERO_STRUCT(earop);

      earop.in.pol = lsa_pol;

      earop.in.sid = &gsop.out.sids[i].sid;

      if(!cac_LsaEnumAccountRights(hnd, mem_ctx, &earop)) {
         fprintf(stderr, "Could not enumerate account rights.\n Error: %s\n", nt_errstr(hnd->status));
      }

      int j;
      printf( "Rights: ");
      for(j = 0; j < earop.out.num_privs; j++) {
         printf("  %s\n", earop.out.priv_names[j]);
      }

      printf("\n");


      i++;
   }

   /*if we want a partial success to occur below, then add the server's SIDs to the end of the array*/
   if(sim_partial) {
      sid_buf[i] = fsop.out.local_sid->sid;
      sid_buf[i+1] = fsop.out.domain_sid->sid;
   }

   fprintf(stdout, "Looking up Names from SIDs\n");

   struct LsaGetNamesFromSids gnop;
   ZERO_STRUCT(gnop);

   gnop.in.pol       = lsa_pol;
   gnop.in.num_sids  = num_sids;
   gnop.in.sids      = sid_buf;

   result = cac_LsaGetNamesFromSids(hnd, mem_ctx, &gnop);

   if(!result) {
      fprintf(stderr, "Could not lookup any names!.\n Error: %s\n", nt_errstr(hnd->status));
      goto done;
   }

   if(result == CAC_PARTIAL_SUCCESS) {
      fprintf(stdout, "\nNot all SIDs could be looked up.\n. The following SIDs were not found:\n");

      for(i = 0; i < (num_sids - gnop.out.num_found); i++) {
         fprintf(stdout, "SID: %s\n", sid_string_static(&gnop.out.unknown[i]));
      }

      fprintf(stdout, "\n");
   }

   fprintf(stdout, "%d SIDs were resolved: \n", gnop.out.num_found);
   for(i = 0; i < gnop.out.num_found; i++) {
      fprintf(stdout, " SID: %s\n Name: %s\n", sid_string_static(&gnop.out.sids[i].sid), gsop.out.sids[i].name);
   }
   
done:

   if(!cac_LsaClosePolicy(hnd, mem_ctx, lsa_pol)) {
      fprintf(stderr, "Could not close LSA policy handle.\n Error: %s\n", nt_errstr(hnd->status));
   }
   else {
      fprintf(stdout, "Closed Policy handle.\n");
   }

   cac_FreeHandle(hnd);
   talloc_destroy(mem_ctx);

   return 0;
}