r4375: Implement samr_OpenAlias, samr_QueryAliasInfo and samr_SetAliasInfo. Fix IDL
authorVolker Lendecke <vlendec@samba.org>
Mon, 27 Dec 2004 11:27:30 +0000 (11:27 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:07:39 +0000 (13:07 -0500)
for samr_SetAliasInfo.

Volker
(This used to be commit d70e2371903fb21e24ab2e23d04ee4b0b2ef55e5)

source4/librpc/idl/samr.idl
source4/rpc_server/samr/dcesrv_samr.c
source4/torture/rpc/samr.c

index 58e0601606f2783d06654a6fd277bbca4bddb548..38e16011e140f032f8ad9731fbe675999e2c311e 100644 (file)
                samr_String description;
        } samr_AliasInfoAll;
 
+       typedef enum {
+               AliasInfoAll          = 1,
+               AliasInfoName         = 2,
+               AliasInfoDescription  = 3
+       } AliasInfo;
+
        typedef union {
-               [case(1)] samr_AliasInfoAll all;
-               [case(2)] samr_String name;
-               [case(3)] samr_String description;
+               [case(AliasInfoAll)] samr_AliasInfoAll all;
+               [case(AliasInfoName)] samr_String name;
+               [case(AliasInfoDescription)] samr_String description;
        } samr_AliasInfo;
 
        NTSTATUS samr_QueryAliasInfo(
        NTSTATUS samr_SetAliasInfo(
                [in,ref]                  policy_handle  *alias_handle,
                [in]                      uint16          level,
-               [in,switch_is(level)]     samr_AliasInfo  info
+               [in,switch_is(level),ref] samr_AliasInfo  *info
                );
 
        /************************/
index 6ab50fa4df3b7ea1ae0cbe0262c00e27a06db0fe..59f5ec9d8a7203904275924fe2f82fc0858c5bbd 100644 (file)
@@ -1599,7 +1599,75 @@ static NTSTATUS samr_SetMemberAttributesOfGroup(struct dcesrv_call_state *dce_ca
 static NTSTATUS samr_OpenAlias(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct samr_OpenAlias *r)
 {
-       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+       struct samr_domain_state *d_state;
+       struct samr_account_state *a_state;
+       struct dcesrv_handle *h;
+       const char *aliasname, *sidstr;
+       struct ldb_message **msgs;
+       struct dcesrv_handle *g_handle;
+       const char * const attrs[2] = { "sAMAccountName", NULL };
+       int ret;
+
+       ZERO_STRUCTP(r->out.alias_handle);
+
+       DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
+
+       d_state = h->data;
+
+       /* form the alias SID */
+       sidstr = talloc_asprintf(mem_ctx, "%s-%u", d_state->domain_sid,
+                                r->in.rid);
+       if (sidstr == NULL)
+               return NT_STATUS_NO_MEMORY;
+
+       /* search for the group record */
+       ret = samdb_search(d_state->sam_ctx,
+                          mem_ctx, d_state->domain_dn, &msgs, attrs,
+                          "(&(objectSid=%s)(objectclass=group)"
+                          "(|(grouptype=%s)(grouptype=%s)))",
+                          sidstr,
+                          ldb_hexstr(mem_ctx, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP),
+                          ldb_hexstr(mem_ctx, GTYPE_SECURITY_DOMAIN_LOCAL_GROUP));
+       if (ret == 0) {
+               return NT_STATUS_NO_SUCH_ALIAS;
+       }
+       if (ret != 1) {
+               DEBUG(0,("Found %d records matching sid %s\n", ret, sidstr));
+               return NT_STATUS_INTERNAL_DB_CORRUPTION;
+       }
+
+       aliasname = samdb_result_string(msgs[0], "sAMAccountName", NULL);
+       if (aliasname == NULL) {
+               DEBUG(0,("sAMAccountName field missing for sid %s\n", sidstr));
+               return NT_STATUS_INTERNAL_DB_CORRUPTION;
+       }
+
+       a_state = talloc_p(d_state, struct samr_account_state);
+       if (!a_state) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       a_state->sam_ctx = d_state->sam_ctx;
+       a_state->access_mask = r->in.access_mask;
+       a_state->domain_state = talloc_reference(a_state, d_state);
+       a_state->account_dn = talloc_steal(a_state, msgs[0]->dn);
+       a_state->account_sid = talloc_steal(a_state, sidstr);
+       a_state->account_name = talloc_strdup(a_state, aliasname);
+       if (!a_state->account_name) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       /* create the policy handle */
+       g_handle = dcesrv_handle_new(dce_call->conn, SAMR_HANDLE_ALIAS);
+       if (!g_handle) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       g_handle->data = a_state;
+       g_handle->destroy = samr_handle_destroy;
+
+       *r->out.alias_handle = g_handle->wire_handle;
+
+       return NT_STATUS_OK;
 }
 
 
@@ -1609,7 +1677,52 @@ static NTSTATUS samr_OpenAlias(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
 static NTSTATUS samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct samr_QueryAliasInfo *r)
 {
-       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+       struct dcesrv_handle *h;
+       struct samr_account_state *a_state;
+       struct ldb_message *msg, **res;
+       const char * const attrs[4] = { "sAMAccountName", "description",
+                                       "numMembers", NULL };
+       int ret;
+
+       r->out.info = NULL;
+
+       DCESRV_PULL_HANDLE(h, r->in.alias_handle, SAMR_HANDLE_ALIAS);
+
+       a_state = h->data;
+
+       /* pull all the alias attributes */
+       ret = samdb_search(a_state->sam_ctx, mem_ctx, NULL, &res, attrs,
+                          "dn=%s", a_state->account_dn);
+       if (ret != 1) {
+               return NT_STATUS_INTERNAL_DB_CORRUPTION;
+       }
+       msg = res[0];
+
+       /* allocate the info structure */
+       r->out.info = talloc_p(mem_ctx, union samr_AliasInfo);
+       if (r->out.info == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       ZERO_STRUCTP(r->out.info);
+
+       switch(r->in.level) {
+       case AliasInfoAll:
+               QUERY_STRING(msg, all.name.string, "sAMAccountName");
+               QUERY_UINT  (msg, all.num_members, "numMembers");
+               QUERY_STRING(msg, all.description.string, "description");
+               break;
+       case AliasInfoName:
+               QUERY_STRING(msg, name.string, "sAMAccountName");
+               break;
+       case AliasInfoDescription:
+               QUERY_STRING(msg, description.string, "description");
+               break;
+       default:
+               r->out.info = NULL;
+               return NT_STATUS_INVALID_INFO_CLASS;
+       }
+       
+       return NT_STATUS_OK;
 }
 
 
@@ -1619,7 +1732,42 @@ static NTSTATUS samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, TALLOC_C
 static NTSTATUS samr_SetAliasInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct samr_SetAliasInfo *r)
 {
-       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+       struct dcesrv_handle *h;
+       struct samr_account_state *a_state;
+       struct ldb_message mod, *msg = &mod;
+       int ret;
+
+       DCESRV_PULL_HANDLE(h, r->in.alias_handle, SAMR_HANDLE_ALIAS);
+
+       a_state = h->data;
+
+       ZERO_STRUCT(mod);
+       mod.dn = talloc_strdup(mem_ctx, a_state->account_dn);
+       if (!mod.dn) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       switch (r->in.level) {
+       case AliasInfoDescription:
+               SET_STRING(msg, description.string,         "description");
+               break;
+       case AliasInfoName:
+               /* On W2k3 this does not change the name, it changes the
+                * sAMAccountName attribute */
+               SET_STRING(msg, name.string,                "sAMAccountName");
+               break;
+       default:
+               return NT_STATUS_INVALID_INFO_CLASS;
+       }
+
+       /* modify the samdb record */
+       ret = samdb_replace(a_state->sam_ctx, mem_ctx, &mod);
+       if (ret != 0) {
+               /* we really need samdb.c to return NTSTATUS */
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       return NT_STATUS_OK;
 }
 
 
index c7456e2fdad3e67b84cdaa3266742bda138caeb5..66cc8a5d2659166fe42ad31a1e40775598d20e19 100644 (file)
@@ -630,8 +630,8 @@ static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                r.in.alias_handle = handle;
                r.in.level = levels[i];
                switch (r.in.level) {
-                   case 2 : init_samr_String(&r.in.info.name,TEST_ALIASNAME); break;
-                   case 3 : init_samr_String(&r.in.info.description,
+                   case 2 : init_samr_String(&r.in.info->name,TEST_ALIASNAME); break;
+                   case 3 : init_samr_String(&r.in.info->description,
                                "Test Description, should test I18N as well"); break;
                }