root/source4/torture/rpc/lsa_lookup.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. open_policy
  2. get_domainsid
  3. lookup_sids
  4. sid_type_lookup
  5. test_lookupsids
  6. get_downleveltrust
  7. torture_rpc_lsa_lookup
  8. test_LookupSidsReply
  9. torture_rpc_lsa_lookup_sids

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    test suite for lsa rpc lookup operations
   4 
   5    Copyright (C) Volker Lendecke 2006
   6    
   7    This program is free software; you can redistribute it and/or modify
   8    it under the terms of the GNU General Public License as published by
   9    the Free Software Foundation; either version 3 of the License, or
  10    (at your option) any later version.
  11    
  12    This program is distributed in the hope that it will be useful,
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15    GNU General Public License for more details.
  16    
  17    You should have received a copy of the GNU General Public License
  18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19 */
  20 
  21 #include "includes.h"
  22 #include "torture/torture.h"
  23 #include "lib/events/events.h"
  24 #include "libnet/libnet_join.h"
  25 #include "torture/rpc/rpc.h"
  26 #include "librpc/gen_ndr/ndr_lsa_c.h"
  27 #include "libcli/security/security.h"
  28 
  29 static bool open_policy(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
  30                         struct policy_handle **handle)
  31 {
  32         struct lsa_ObjectAttribute attr;
  33         struct lsa_QosInfo qos;
  34         struct lsa_OpenPolicy2 r;
  35         NTSTATUS status;
  36 
  37         *handle = talloc(mem_ctx, struct policy_handle);
  38         if (!*handle) {
  39                 return false;
  40         }
  41 
  42         qos.len = 0;
  43         qos.impersonation_level = 2;
  44         qos.context_mode = 1;
  45         qos.effective_only = 0;
  46 
  47         attr.len = 0;
  48         attr.root_dir = NULL;
  49         attr.object_name = NULL;
  50         attr.attributes = 0;
  51         attr.sec_desc = NULL;
  52         attr.sec_qos = &qos;
  53 
  54         r.in.system_name = "\\";
  55         r.in.attr = &attr;
  56         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
  57         r.out.handle = *handle;
  58 
  59         status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r);
  60 
  61         return NT_STATUS_IS_OK(status);
  62 }
  63 
  64 static bool get_domainsid(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
  65                           struct policy_handle *handle,
  66                           struct dom_sid **sid)
  67 {
  68         struct lsa_QueryInfoPolicy r;
  69         union lsa_PolicyInformation *info = NULL;
  70         NTSTATUS status;
  71 
  72         r.in.level = LSA_POLICY_INFO_DOMAIN;
  73         r.in.handle = handle;
  74         r.out.info = &info;
  75 
  76         status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r);
  77         if (!NT_STATUS_IS_OK(status)) return false;
  78 
  79         *sid = info->domain.sid;
  80         return true;
  81 }
  82 
  83 static NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, uint16_t level,
     /* [<][>][^][v][top][bottom][index][help] */
  84                             struct dcerpc_pipe *p,
  85                             struct policy_handle *handle,
  86                             struct dom_sid **sids, uint32_t num_sids,
  87                             struct lsa_TransNameArray *names)
  88 {
  89         struct lsa_LookupSids r;
  90         struct lsa_SidArray sidarray;
  91         struct lsa_RefDomainList *domains;
  92         uint32_t count = 0;
  93         uint32_t i;
  94 
  95         names->count = 0;
  96         names->names = NULL;
  97 
  98         sidarray.num_sids = num_sids;
  99         sidarray.sids = talloc_array(mem_ctx, struct lsa_SidPtr, num_sids);
 100 
 101         for (i=0; i<num_sids; i++) {
 102                 sidarray.sids[i].sid = sids[i];
 103         }
 104 
 105         r.in.handle = handle;
 106         r.in.sids = &sidarray;
 107         r.in.names = names;
 108         r.in.level = level;
 109         r.in.count = &count;
 110         r.out.names = names;
 111         r.out.count = &count;
 112         r.out.domains = &domains;
 113 
 114         return dcerpc_lsa_LookupSids(p, mem_ctx, &r);
 115 }
 116 
 117 static const char *sid_type_lookup(enum lsa_SidType r)
     /* [<][>][^][v][top][bottom][index][help] */
 118 {
 119         switch (r) {
 120                 case SID_NAME_USE_NONE: return "SID_NAME_USE_NONE"; break;
 121                 case SID_NAME_USER: return "SID_NAME_USER"; break;
 122                 case SID_NAME_DOM_GRP: return "SID_NAME_DOM_GRP"; break;
 123                 case SID_NAME_DOMAIN: return "SID_NAME_DOMAIN"; break;
 124                 case SID_NAME_ALIAS: return "SID_NAME_ALIAS"; break;
 125                 case SID_NAME_WKN_GRP: return "SID_NAME_WKN_GRP"; break;
 126                 case SID_NAME_DELETED: return "SID_NAME_DELETED"; break;
 127                 case SID_NAME_INVALID: return "SID_NAME_INVALID"; break;
 128                 case SID_NAME_UNKNOWN: return "SID_NAME_UNKNOWN"; break;
 129                 case SID_NAME_COMPUTER: return "SID_NAME_COMPUTER"; break;
 130         }
 131         return "Invalid sid type\n";
 132 }
 133 
 134 static bool test_lookupsids(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
 135                             struct policy_handle *handle,
 136                             struct dom_sid **sids, uint32_t num_sids,
 137                             int level, NTSTATUS expected_result, 
 138                             enum lsa_SidType *types)
 139 {
 140         struct lsa_TransNameArray names;
 141         NTSTATUS status;
 142         uint32_t i;
 143         bool ret = true;
 144 
 145         status = lookup_sids(mem_ctx, level, p, handle, sids, num_sids,
 146                              &names);
 147         if (!NT_STATUS_EQUAL(status, expected_result)) {
 148                 printf("For level %d expected %s, got %s\n",
 149                        level, nt_errstr(expected_result),
 150                        nt_errstr(status));
 151                 return false;
 152         }
 153 
 154         if (!NT_STATUS_EQUAL(status, NT_STATUS_OK) &&
 155             !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
 156                 return true;
 157         }
 158 
 159         for (i=0; i<num_sids; i++) {
 160                 if (names.names[i].sid_type != types[i]) {
 161                         printf("In level %d, for sid %s expected %s, "
 162                                "got %s\n", level,
 163                                dom_sid_string(mem_ctx, sids[i]),
 164                                sid_type_lookup(types[i]),
 165                                sid_type_lookup(names.names[i].sid_type));
 166                         ret = false;
 167                 }
 168         }
 169         return ret;
 170 }
 171 
 172 static bool get_downleveltrust(struct torture_context *tctx, struct dcerpc_pipe *p,
     /* [<][>][^][v][top][bottom][index][help] */
 173                                struct policy_handle *handle,
 174                                struct dom_sid **sid)
 175 {
 176         struct lsa_EnumTrustDom r;
 177         uint32_t resume_handle = 0;
 178         struct lsa_DomainList domains;
 179         NTSTATUS status;
 180         int i;
 181 
 182         r.in.handle = handle;
 183         r.in.resume_handle = &resume_handle;
 184         r.in.max_size = 1000;
 185         r.out.domains = &domains;
 186         r.out.resume_handle = &resume_handle;
 187 
 188         status = dcerpc_lsa_EnumTrustDom(p, tctx, &r);
 189 
 190         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))
 191                 torture_fail(tctx, "no trusts");
 192 
 193         if (domains.count == 0) {
 194                 torture_fail(tctx, "no trusts");
 195         }
 196 
 197         for (i=0; i<domains.count; i++) {
 198                 struct lsa_QueryTrustedDomainInfoBySid q;
 199                 union lsa_TrustedDomainInfo *info = NULL;
 200 
 201                 if (domains.domains[i].sid == NULL)
 202                         continue;
 203 
 204                 q.in.handle = handle;
 205                 q.in.dom_sid = domains.domains[i].sid;
 206                 q.in.level = 6;
 207                 q.out.info = &info;
 208 
 209                 status = dcerpc_lsa_QueryTrustedDomainInfoBySid(p, tctx, &q);
 210                 if (!NT_STATUS_IS_OK(status)) continue;
 211 
 212                 if ((info->info_ex.trust_direction & 2) &&
 213                     (info->info_ex.trust_type == 1)) {
 214                         *sid = domains.domains[i].sid;
 215                         return true;
 216                 }
 217         }
 218 
 219         torture_fail(tctx, "I need a AD DC with an outgoing trust to NT4");
 220 }
 221 
 222 #define NUM_SIDS 8
 223 
 224 bool torture_rpc_lsa_lookup(struct torture_context *torture)
     /* [<][>][^][v][top][bottom][index][help] */
 225 {
 226         NTSTATUS status;
 227         struct dcerpc_pipe *p;
 228         bool ret = true;
 229         struct policy_handle *handle;
 230         struct dom_sid *dom_sid;
 231         struct dom_sid *trusted_sid;
 232         struct dom_sid *sids[NUM_SIDS];
 233 
 234         status = torture_rpc_connection(torture, &p, &ndr_table_lsarpc);
 235         if (!NT_STATUS_IS_OK(status)) {
 236                 torture_fail(torture, "unable to connect to table");
 237         }
 238 
 239         ret &= open_policy(torture, p, &handle);
 240         if (!ret) return false;
 241 
 242         ret &= get_domainsid(torture, p, handle, &dom_sid);
 243         if (!ret) return false;
 244 
 245         ret &= get_downleveltrust(torture, p, handle, &trusted_sid);
 246         if (!ret) return false;
 247 
 248         torture_comment(torture, "domain sid: %s\n", 
 249                                         dom_sid_string(torture, dom_sid));
 250 
 251         sids[0] = dom_sid_parse_talloc(torture, "S-1-1-0");
 252         sids[1] = dom_sid_parse_talloc(torture, "S-1-5-4");
 253         sids[2] = dom_sid_parse_talloc(torture, "S-1-5-32");
 254         sids[3] = dom_sid_parse_talloc(torture, "S-1-5-32-545");
 255         sids[4] = dom_sid_dup(torture, dom_sid);
 256         sids[5] = dom_sid_add_rid(torture, dom_sid, 512);
 257         sids[6] = dom_sid_dup(torture, trusted_sid);
 258         sids[7] = dom_sid_add_rid(torture, trusted_sid, 512);
 259 
 260         ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 0,
 261                                NT_STATUS_INVALID_PARAMETER, NULL);
 262 
 263         {
 264                 enum lsa_SidType types[NUM_SIDS] =
 265                         { SID_NAME_WKN_GRP, SID_NAME_WKN_GRP, SID_NAME_DOMAIN,
 266                           SID_NAME_ALIAS, SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
 267                           SID_NAME_DOMAIN, SID_NAME_DOM_GRP };
 268 
 269                 ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 1,
 270                                        NT_STATUS_OK, types);
 271         }
 272 
 273         {
 274                 enum lsa_SidType types[NUM_SIDS] =
 275                         { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
 276                           SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
 277                           SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
 278                           SID_NAME_DOMAIN, SID_NAME_DOM_GRP };
 279                 ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 2,
 280                                        STATUS_SOME_UNMAPPED, types);
 281         }
 282 
 283         {
 284                 enum lsa_SidType types[NUM_SIDS] =
 285                         { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
 286                           SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
 287                           SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
 288                           SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
 289                 ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 3,
 290                                        STATUS_SOME_UNMAPPED, types);
 291         }
 292 
 293         {
 294                 enum lsa_SidType types[NUM_SIDS] =
 295                         { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
 296                           SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
 297                           SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
 298                           SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
 299                 ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 4,
 300                                        STATUS_SOME_UNMAPPED, types);
 301         }
 302 
 303         ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 5,
 304                                NT_STATUS_NONE_MAPPED, NULL);
 305 
 306         {
 307                 enum lsa_SidType types[NUM_SIDS] =
 308                         { SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
 309                           SID_NAME_UNKNOWN, SID_NAME_UNKNOWN,
 310                           SID_NAME_DOMAIN, SID_NAME_DOM_GRP,
 311                           SID_NAME_UNKNOWN, SID_NAME_UNKNOWN };
 312                 ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 6,
 313                                        STATUS_SOME_UNMAPPED, types);
 314         }
 315 
 316         ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 7,
 317                                NT_STATUS_INVALID_PARAMETER, NULL);
 318         ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 8,
 319                                NT_STATUS_INVALID_PARAMETER, NULL);
 320         ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 9,
 321                                NT_STATUS_INVALID_PARAMETER, NULL);
 322         ret &= test_lookupsids(torture, p, handle, sids, NUM_SIDS, 10,
 323                                NT_STATUS_INVALID_PARAMETER, NULL);
 324 
 325         return ret;
 326 }
 327 
 328 static bool test_LookupSidsReply(struct torture_context *tctx,
     /* [<][>][^][v][top][bottom][index][help] */
 329                                  struct dcerpc_pipe *p)
 330 {
 331         struct policy_handle *handle;
 332 
 333         struct dom_sid **sids;
 334         uint32_t num_sids = 1;
 335 
 336         struct lsa_LookupSids r;
 337         struct lsa_SidArray sidarray;
 338         struct lsa_RefDomainList *domains = NULL;
 339         struct lsa_TransNameArray names;
 340         uint32_t count = 0;
 341 
 342         uint32_t i;
 343         NTSTATUS status;
 344         const char *dom_sid = "S-1-5-21-1111111111-2222222222-3333333333";
 345         const char *dom_admin_sid;
 346 
 347         if (!open_policy(tctx, p, &handle)) {
 348                 return false;
 349         }
 350 
 351         dom_admin_sid = talloc_asprintf(tctx, "%s-%d", dom_sid, 512);
 352 
 353         sids = talloc_array(tctx, struct dom_sid *, num_sids);
 354 
 355         sids[0] = dom_sid_parse_talloc(tctx, dom_admin_sid);
 356 
 357         names.count = 0;
 358         names.names = NULL;
 359 
 360         sidarray.num_sids = num_sids;
 361         sidarray.sids = talloc_array(tctx, struct lsa_SidPtr, num_sids);
 362 
 363         for (i=0; i<num_sids; i++) {
 364                 sidarray.sids[i].sid = sids[i];
 365         }
 366 
 367         r.in.handle     = handle;
 368         r.in.sids       = &sidarray;
 369         r.in.names      = &names;
 370         r.in.level      = LSA_LOOKUP_NAMES_ALL;
 371         r.in.count      = &count;
 372         r.out.names     = &names;
 373         r.out.count     = &count;
 374         r.out.domains   = &domains;
 375 
 376         status = dcerpc_lsa_LookupSids(p, tctx, &r);
 377 
 378         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NONE_MAPPED,
 379                 "unexpected error code");
 380 
 381         torture_assert_int_equal(tctx, names.count, num_sids,
 382                 "unexpected names count");
 383         torture_assert(tctx, names.names,
 384                 "unexpected names pointer");
 385         torture_assert_str_equal(tctx, names.names[0].name.string, dom_admin_sid,
 386                 "unexpected names[0].string");
 387 
 388 #if 0
 389         /* vista sp1 passes, w2k3 sp2 fails */
 390         torture_assert_int_equal(tctx, domains->count, num_sids,
 391                 "unexpected domains count");
 392         torture_assert(tctx, domains->domains,
 393                 "unexpected domains pointer");
 394         torture_assert_str_equal(tctx, dom_sid_string(tctx, domains->domains[0].sid), dom_sid,
 395                 "unexpected domain sid");
 396 #endif
 397 
 398         return true;
 399 }
 400 
 401 /* check for lookup sids results */
 402 struct torture_suite *torture_rpc_lsa_lookup_sids(TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 403 {
 404         struct torture_suite *suite;
 405         struct torture_rpc_tcase *tcase;
 406 
 407         suite = torture_suite_create(mem_ctx, "LSA-LOOKUPSIDS");
 408         tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
 409                                                   &ndr_table_lsarpc);
 410 
 411         torture_rpc_tcase_add_test(tcase, "LookupSidsReply", test_LookupSidsReply);
 412 
 413         return suite;
 414 }

/* [<][>][^][v][top][bottom][index][help] */