r4414: Various bits&pieces:
authorVolker Lendecke <vlendec@samba.org>
Thu, 30 Dec 2004 17:01:49 +0000 (17:01 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:07:46 +0000 (13:07 -0500)
* Implement samr_search_domain, filter out all elements with no "objectSid"
  attribute and all objects outside a specified domain sid.

* Minor cleanups in dcerpc_samr.c due to that.

* Implement srvsvc_NetSrvGetInfo level 100. A quick hack to get usrmgr.exe
  one step further.

* Same for samr_info_DomInfo1.

Volker

source/dsdb/samdb/samdb.c
source/rpc_server/samr/dcesrv_samr.c
source/rpc_server/srvsvc/dcesrv_srvsvc.c

index 934e6c240f34c27e34dc0e6c9a46eafb8f63bdc6..8188bf20160c02efff46ad41d7d250a9a3b2b075 100644 (file)
@@ -54,6 +54,49 @@ int samdb_search(void *ctx,
        return count;
 }
 
+/*
+  search the sam for the specified attributes in a specific domain, filter on
+  objectSid being in domain_sid.
+*/
+int samdb_search_domain(void *ctx,
+                       TALLOC_CTX *mem_ctx, 
+                       const char *basedn,
+                       struct ldb_message ***res,
+                       const char * const *attrs,
+                       const struct dom_sid *domain_sid,
+                       const char *format, ...)  _PRINTF_ATTRIBUTE(7,8)
+{
+       struct ldb_wrap *sam_ctx = ctx;
+       va_list ap;
+       int i, count;
+
+       va_start(ap, format);
+       count = gendb_search_v(sam_ctx->ldb, mem_ctx, basedn, res, attrs,
+                              format, ap);
+       va_end(ap);
+
+       i=0;
+
+       while (i<count) {
+               struct dom_sid *entry_sid;
+
+               entry_sid = samdb_result_dom_sid(mem_ctx, (*res)[i],
+                                                "objectSid");
+
+               if ((entry_sid == NULL) ||
+                   (!dom_sid_in_domain(domain_sid, entry_sid))) {
+
+                       /* Delete that entry from the result set */
+                       (*res)[i] = (*res)[count-1];
+                       count -= 1;
+                       continue;
+               }
+               i += 1;
+       }
+
+       return count;
+}
+
 /*
   free up a search result
 */
index 216feaa52aae3b165745481122bd3fdc36a7688c..d16afa28023b00c89ecb3483596aab44e7d75cda 100644 (file)
@@ -340,6 +340,39 @@ static NTSTATUS samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *
        return NT_STATUS_OK;
 }
 
+/*
+  return DomInfo1
+*/
+static NTSTATUS samr_info_DomInfo1(struct samr_domain_state *state,
+                                  TALLOC_CTX *mem_ctx,
+                                  struct samr_DomInfo1 *info)
+{
+       const char * const attrs[] = { "minPwdLength", "pwdHistoryLength",
+                                      "pwdProperties", "maxPwdAge",
+                                      "minPwdAge", NULL };
+       int ret;
+       struct ldb_message **res;
+
+       ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, 
+                          "dn=%s", state->domain_dn);
+       if (ret != 1) {
+               return NT_STATUS_INTERNAL_DB_CORRUPTION;
+       }
+
+       info->min_password_length =
+               samdb_result_uint(res[0], "minPwdLength", 0);
+       info->password_history_length =
+               samdb_result_uint(res[0], "pwdHistoryLength", 0);
+       info->password_properties = 
+               samdb_result_uint(res[0], "pwdProperties", 0);
+       info->max_password_age = 
+               samdb_result_int64(res[0], "maxPwdAge", 0);
+       info->min_password_age = 
+               samdb_result_int64(res[0], "minPwdAge", 0);
+
+       return NT_STATUS_OK;
+}
+
 /*
   return DomInfo2
 */
@@ -399,6 +432,9 @@ static NTSTATUS samr_QueryDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_
        ZERO_STRUCTP(r->out.info);
 
        switch (r->in.level) {
+       case 1:
+               return samr_info_DomInfo1(d_state, mem_ctx,
+                                         &r->out.info->info1);
        case 2:
                return samr_info_DomInfo2(d_state, mem_ctx, &r->out.info->info2);
        }
@@ -568,14 +604,19 @@ static NTSTATUS samr_EnumDomainGroups(struct dcesrv_call_state *dce_call, TALLOC
        DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
 
        d_state = h->data;
+
+       domain_sid = dom_sid_parse_talloc(mem_ctx, d_state->domain_sid);
+       if (domain_sid == NULL)
+               return NT_STATUS_NO_MEMORY;
        
        /* search for all domain groups in this domain. This could possibly be
           cached and resumed based on resume_key */
-       ldb_cnt = samdb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn,
-                              &res, attrs, 
-                              "(&(grouptype=%s)(objectclass=group))",
-                              ldb_hexstr(mem_ctx,
-                                         GTYPE_SECURITY_GLOBAL_GROUP));
+       ldb_cnt = samdb_search_domain(d_state->sam_ctx, mem_ctx,
+                                     d_state->domain_dn, &res, attrs,
+                                     domain_sid,
+                                     "(&(grouptype=%s)(objectclass=group))",
+                                     ldb_hexstr(mem_ctx,
+                                                GTYPE_SECURITY_GLOBAL_GROUP));
        if (ldb_cnt == -1) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
@@ -590,22 +631,17 @@ static NTSTATUS samr_EnumDomainGroups(struct dcesrv_call_state *dce_call, TALLOC
        }
 
        count = 0;
-       domain_sid = dom_sid_parse_talloc(mem_ctx, d_state->domain_sid);
 
        for (i=0;i<ldb_cnt;i++) {
-               struct dom_sid *alias_sid;
+               struct dom_sid *group_sid;
 
-               alias_sid = samdb_result_dom_sid(mem_ctx, res[i],
+               group_sid = samdb_result_dom_sid(mem_ctx, res[i],
                                                 "objectSid");
-
-               if (alias_sid == NULL)
+               if (group_sid == NULL)
                        continue;
 
-               if (!dom_sid_in_domain(domain_sid, alias_sid))
-                       continue;
-               
                entries[count].idx =
-                       alias_sid->sub_auths[alias_sid->num_auths-1];
+                       group_sid->sub_auths[group_sid->num_auths-1];
                entries[count].name.string =
                        samdb_result_string(res[i], "sAMAccountName", "");
                count += 1;
@@ -1069,17 +1105,22 @@ static NTSTATUS samr_EnumDomainAliases(struct dcesrv_call_state *dce_call, TALLO
        DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
 
        d_state = h->data;
+
+       domain_sid = dom_sid_parse_talloc(mem_ctx, d_state->domain_sid);
+       if (domain_sid == NULL)
+               return NT_STATUS_NO_MEMORY;
        
        /* search for all domain groups in this domain. This could possibly be
           cached and resumed based on resume_key */
-       ldb_cnt = samdb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn,
-                              &res, attrs, 
-                              "(&(|(grouptype=%s)(grouptype=%s)))"
-                              "(objectclass=group))",
-                              ldb_hexstr(mem_ctx,
-                                         GTYPE_SECURITY_BUILTIN_LOCAL_GROUP),
-                              ldb_hexstr(mem_ctx,
-                                         GTYPE_SECURITY_DOMAIN_LOCAL_GROUP));
+       ldb_cnt = samdb_search_domain(d_state->sam_ctx, mem_ctx,
+                                     d_state->domain_dn,
+                                     &res, attrs, domain_sid,
+                                     "(&(|(grouptype=%s)(grouptype=%s)))"
+                                     "(objectclass=group))",
+                                     ldb_hexstr(mem_ctx,
+                                                GTYPE_SECURITY_BUILTIN_LOCAL_GROUP),
+                                     ldb_hexstr(mem_ctx,
+                                                GTYPE_SECURITY_DOMAIN_LOCAL_GROUP));
        if (ldb_cnt == -1) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
@@ -1094,7 +1135,6 @@ static NTSTATUS samr_EnumDomainAliases(struct dcesrv_call_state *dce_call, TALLO
        }
 
        count = 0;
-       domain_sid = dom_sid_parse_talloc(mem_ctx, d_state->domain_sid);
 
        for (i=0;i<ldb_cnt;i++) {
                struct dom_sid *alias_sid;
@@ -1105,9 +1145,6 @@ static NTSTATUS samr_EnumDomainAliases(struct dcesrv_call_state *dce_call, TALLO
                if (alias_sid == NULL)
                        continue;
 
-               if (!dom_sid_in_domain(domain_sid, alias_sid))
-                       continue;
-               
                entries[count].idx =
                        alias_sid->sub_auths[alias_sid->num_auths-1];
                entries[count].name.string =
@@ -1201,9 +1238,14 @@ static NTSTATUS samr_GetAliasMembership(struct dcesrv_call_state *dce_call, TALL
                                return NT_STATUS_NO_MEMORY;
                }
 
-               count = samdb_search(d_state->sam_ctx, mem_ctx,
-                                    d_state->domain_dn, &res, attrs,
-                                    "%s))", filter);
+               domain_sid = dom_sid_parse_talloc(mem_ctx,
+                                                 d_state->domain_sid);
+               if (domain_sid == NULL)
+                       return NT_STATUS_NO_MEMORY;
+
+               count = samdb_search_domain(d_state->sam_ctx, mem_ctx,
+                                           d_state->domain_dn, &res, attrs,
+                                           domain_sid, "%s))", filter);
                if (count < 0)
                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
@@ -1213,10 +1255,6 @@ static NTSTATUS samr_GetAliasMembership(struct dcesrv_call_state *dce_call, TALL
        if (r->out.rids->ids == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       domain_sid = dom_sid_parse_talloc(mem_ctx, d_state->domain_sid);
-       if (domain_sid == NULL)
-               return NT_STATUS_NO_MEMORY;
-
        for (i=0; i<count; i++) {
                struct dom_sid *alias_sid;
 
@@ -1227,9 +1265,6 @@ static NTSTATUS samr_GetAliasMembership(struct dcesrv_call_state *dce_call, TALL
                        continue;
                }
 
-               if (!dom_sid_in_domain(domain_sid, alias_sid))
-                       continue;
-
                r->out.rids->ids[r->out.rids->count] =
                        alias_sid->sub_auths[alias_sid->num_auths-1];
                r->out.rids->count += 1;
@@ -2801,6 +2836,7 @@ static NTSTATUS samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, TALLOC
        struct samr_account_state *a_state;
        struct samr_domain_state *d_state;
        struct ldb_message **res;
+       struct dom_sid *domain_sid;
        const char * const attrs[2] = { "objectSid", NULL };
        struct samr_RidArray *array;
        int count;
@@ -2809,11 +2845,16 @@ static NTSTATUS samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, TALLOC
 
        a_state = h->data;
        d_state = a_state->domain_state;
+       domain_sid = dom_sid_parse_talloc(mem_ctx, d_state->domain_sid);
+       if (domain_sid == NULL)
+               return NT_STATUS_NO_MEMORY;
 
-       count = samdb_search(a_state->sam_ctx, mem_ctx, NULL, &res, attrs,
-                            "(&(member=%s)(grouptype=%s)(objectclass=group))",
-                            a_state->account_dn,
-                            ldb_hexstr(mem_ctx, GTYPE_SECURITY_GLOBAL_GROUP));
+       count = samdb_search_domain(a_state->sam_ctx, mem_ctx, NULL, &res,
+                                   attrs, domain_sid,
+                                   "(&(member=%s)(grouptype=%s)(objectclass=group))",
+                                   a_state->account_dn,
+                                   ldb_hexstr(mem_ctx,
+                                              GTYPE_SECURITY_GLOBAL_GROUP));
        if (count < 0)
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
 
@@ -2826,14 +2867,10 @@ static NTSTATUS samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, TALLOC
 
        if (count > 0) {
                int i;
-               struct dom_sid *domain_sid;
-
-               domain_sid = dom_sid_parse_talloc(mem_ctx,
-                                                 d_state->domain_sid);
                array->rid = talloc_array_p(mem_ctx, struct samr_RidType,
                                            count);
 
-               if ((domain_sid == NULL) || (array->rid == NULL))
+               if (array->rid == NULL)
                        return NT_STATUS_NO_MEMORY;
 
                for (i=0; i<count; i++) {
@@ -2846,9 +2883,6 @@ static NTSTATUS samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, TALLOC
                                continue;
                        }
 
-                       if (!dom_sid_in_domain(domain_sid, group_sid))
-                               continue;
-
                        array->rid[array->count].rid =
                                group_sid->sub_auths[group_sid->num_auths-1];
                        array->rid[array->count].type = 7;
@@ -2908,10 +2942,15 @@ static NTSTATUS samr_QueryDisplayInfo(struct dcesrv_call_state *dce_call, TALLOC
                return NT_STATUS_INVALID_INFO_CLASS;
        }
 
-       /* search for all domain groups in this domain. This could possibly be
-          cached and resumed based on resume_key */
-       ldb_cnt = samdb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn,
-                              &res, attrs, "%s", filter);
+       domain_sid = dom_sid_parse_talloc(mem_ctx, d_state->domain_sid);
+       if (domain_sid == NULL)
+               return NT_STATUS_NO_MEMORY;
+
+       /* search for all requested objects in this domain. This could
+          possibly be cached and resumed based on resume_key */
+       ldb_cnt = samdb_search_domain(d_state->sam_ctx, mem_ctx,
+                                     d_state->domain_dn, &res, attrs,
+                                     domain_sid, "%s", filter);
        if (ldb_cnt == -1) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
@@ -2944,7 +2983,6 @@ static NTSTATUS samr_QueryDisplayInfo(struct dcesrv_call_state *dce_call, TALLOC
                return NT_STATUS_NO_MEMORY;
 
        count = 0;
-       domain_sid = dom_sid_parse_talloc(mem_ctx, d_state->domain_sid);
 
        for (i=0; i<ldb_cnt; i++) {
                struct dom_sid *objectsid;
@@ -2954,9 +2992,6 @@ static NTSTATUS samr_QueryDisplayInfo(struct dcesrv_call_state *dce_call, TALLOC
                if (objectsid == NULL)
                        continue;
 
-               if (!dom_sid_in_domain(domain_sid, objectsid))
-                       continue;
-
                switch(r->in.level) {
                case 1:
                        entriesGeneral[count].idx = count;
@@ -3167,7 +3202,22 @@ static NTSTATUS samr_QueryUserInfo2(struct dcesrv_call_state *dce_call, TALLOC_C
 static NTSTATUS samr_QueryDisplayInfo2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct samr_QueryDisplayInfo2 *r)
 {
-       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+       struct samr_QueryDisplayInfo q;
+       NTSTATUS result;
+
+       q.in.domain_handle = r->in.domain_handle;
+       q.in.level = r->in.level;
+       q.in.start_idx = r->in.start_idx;
+       q.in.max_entries = r->in.max_entries;
+       q.in.buf_size = r->in.buf_size;
+
+       result = samr_QueryDisplayInfo(dce_call, mem_ctx, &q);
+
+       r->out.total_size = q.out.total_size;
+       r->out.returned_size = q.out.returned_size;
+       r->out.info = q.out.info;
+
+       return result;
 }
 
 
index 8909fc17a76416d2fa68ed721cfed54cbca5451f..12dcf5b7381c89a1dd87b79dfac4391875de5597 100644 (file)
@@ -666,7 +666,16 @@ static WERROR srvsvc_NetShareCheck(struct dcesrv_call_state *dce_call, TALLOC_CT
 static WERROR srvsvc_NetSrvGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct srvsvc_NetSrvGetInfo *r)
 {
-       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+       if (r->in.level != 100)
+               return WERR_UNKNOWN_LEVEL;
+
+       r->out.info.info100 = talloc_p(mem_ctx, struct srvsvc_NetSrvInfo100);
+       if (r->out.info.info100 == NULL)
+               return WERR_NOMEM;
+
+       r->out.info.info100->platform_id = 500; /* W2k3 returns this */
+       r->out.info.info100->server_unc = lp_netbios_name();
+       return WERR_OK;
 }