Author: tridge Date: 2004-12-19 11:34:19 +0000 (Sun, 19 Dec 2004) New Revision: 4283
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=4283 Log: adding a privilege that an account already has is not an error Modified: branches/SAMBA_4_0/source/rpc_server/lsa/dcesrv_lsa.c Changeset: Modified: branches/SAMBA_4_0/source/rpc_server/lsa/dcesrv_lsa.c =================================================================== --- branches/SAMBA_4_0/source/rpc_server/lsa/dcesrv_lsa.c 2004-12-19 10:58:36 UTC (rev 4282) +++ branches/SAMBA_4_0/source/rpc_server/lsa/dcesrv_lsa.c 2004-12-19 11:34:19 UTC (rev 4283) @@ -878,7 +878,57 @@ return NT_STATUS_OK; } +/* + lsa_EnumAccountRights +*/ +static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, + TALLOC_CTX *mem_ctx, + struct lsa_EnumAccountRights *r) +{ + struct dcesrv_handle *h; + struct lsa_policy_state *state; + int ret, i; + struct ldb_message **res; + const char * const attrs[] = { "privilege", NULL}; + const char *sidstr; + struct ldb_message_element *el; + DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY); + + state = h->data; + + sidstr = dom_sid_string(mem_ctx, r->in.sid); + if (sidstr == NULL) { + return NT_STATUS_NO_MEMORY; + } + + ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, + "objectSid=%s", sidstr); + if (ret != 1) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + el = ldb_msg_find_element(res[0], "privilege"); + if (el == NULL || el->num_values == 0) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + r->out.rights->count = el->num_values; + r->out.rights->names = talloc_array_p(r->out.rights, + struct lsa_String, r->out.rights->count); + if (r->out.rights->names == NULL) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0;i<el->num_values;i++) { + r->out.rights->names[i].string = el->values[i].data; + } + + return NT_STATUS_OK; +} + + + /* helper for lsa_AddAccountRights and lsa_RemoveAccountRights */ @@ -886,7 +936,7 @@ TALLOC_CTX *mem_ctx, struct lsa_policy_state *state, int ldb_flag, - const struct dom_sid *sid, + struct dom_sid *sid, const struct lsa_RightSet *rights) { const char *sidstr; @@ -894,6 +944,7 @@ struct ldb_message_element el; int i, ret; const char *dn; + struct lsa_EnumAccountRights r2; sidstr = dom_sid_string(mem_ctx, sid); if (sidstr == NULL) { @@ -917,22 +968,54 @@ if (el.name == NULL) { return NT_STATUS_NO_MEMORY; } - el.num_values = rights->count; - el.values = talloc_array_p(mem_ctx, struct ldb_val, el.num_values); + + if (ldb_flag == LDB_FLAG_MOD_ADD) { + NTSTATUS status; + + r2.in.handle = &state->handle->wire_handle; + r2.in.sid = sid; + r2.out.rights = talloc_p(mem_ctx, struct lsa_RightSet); + + status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2); + if (!NT_STATUS_IS_OK(status)) { + ZERO_STRUCTP(r2.out.rights); + } + } + + el.num_values = 0; + el.values = talloc_array_p(mem_ctx, struct ldb_val, rights->count); if (el.values == NULL) { return NT_STATUS_NO_MEMORY; } - for (i=0;i<el.num_values;i++) { + for (i=0;i<rights->count;i++) { if (sec_privilege_id(rights->names[i].string) == -1) { return NT_STATUS_NO_SUCH_PRIVILEGE; } - el.values[i].length = strlen(rights->names[i].string); - el.values[i].data = talloc_strdup(mem_ctx, rights->names[i].string); - if (el.values[i].data == NULL) { + + if (ldb_flag == LDB_FLAG_MOD_ADD) { + int j; + for (j=0;j<r2.out.rights->count;j++) { + if (StrCaseCmp(r2.out.rights->names[j].string, + rights->names[i].string) == 0) { + break; + } + } + if (j != r2.out.rights->count) continue; + } + + + el.values[el.num_values].length = strlen(rights->names[i].string); + el.values[el.num_values].data = talloc_strdup(mem_ctx, rights->names[i].string); + if (el.values[el.num_values].data == NULL) { return NT_STATUS_NO_MEMORY; } + el.num_values++; } + if (el.num_values == 0) { + return NT_STATUS_OK; + } + ret = samdb_modify(state->sam_ctx, mem_ctx, &msg); if (ret != 0) { if (ldb_flag == LDB_FLAG_MOD_DELETE) { @@ -944,60 +1027,7 @@ return NT_STATUS_OK; } - /* - lsa_EnumAccountRights -*/ -static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, - TALLOC_CTX *mem_ctx, - struct lsa_EnumAccountRights *r) -{ - struct dcesrv_handle *h; - struct lsa_policy_state *state; - int ret, i; - struct ldb_message **res; - const char * const attrs[] = { "privilege", NULL}; - const char *sidstr; - struct ldb_message_element *el; - - DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY); - - state = h->data; - - sidstr = dom_sid_string(mem_ctx, r->in.sid); - if (sidstr == NULL) { - return NT_STATUS_NO_MEMORY; - } - - ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, - "objectSid=%s", sidstr); - if (ret != 1) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - - el = ldb_msg_find_element(res[0], "privilege"); - if (el == NULL || el->num_values == 0) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - - r->out.rights->count = el->num_values; - r->out.rights->names = talloc_array_p(r->out.rights, - struct lsa_String, r->out.rights->count); - if (r->out.rights->names == NULL) { - return NT_STATUS_NO_MEMORY; - } - - for (i=0;i<el->num_values;i++) { - r->out.rights->names[i].string = el->values[i].data; - } - - return NT_STATUS_OK; -} - - - - -/* lsa_AddPrivilegesToAccount */ static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,