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;
}
|