summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/rpc_server/srvsvc/dcesrv_srvsvc.c206
1 files changed, 204 insertions, 2 deletions
diff --git a/source4/rpc_server/srvsvc/dcesrv_srvsvc.c b/source4/rpc_server/srvsvc/dcesrv_srvsvc.c
index 997cdc81ac..911f997fc0 100644
--- a/source4/rpc_server/srvsvc/dcesrv_srvsvc.c
+++ b/source4/rpc_server/srvsvc/dcesrv_srvsvc.c
@@ -24,8 +24,18 @@
#include "rpc_server/dcerpc_server.h"
#include "librpc/gen_ndr/ndr_srvsvc.h"
#include "rpc_server/common/common.h"
+#include "auth/auth.h"
+#include "libcli/security/security.h"
#include "system/time.h"
+#define SRVSVC_CHECK_ADMIN_ACCESS do { \
+ struct security_token *t = dce_call->conn->auth_state.session_info->security_token; \
+ if (!security_token_has_builtin_administrators(t) && \
+ !security_token_has_sid_string(t, SID_BUILTIN_SERVER_OPERATORS)) { \
+ return WERR_ACCESS_DENIED; \
+ } \
+} while (0)
+
/*
srvsvc_NetCharDevEnum
*/
@@ -547,7 +557,6 @@ static WERROR srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_
r->out.resume_handle = NULL;
/* TODO: - paging of results
- * - access check
*/
switch (r->in.level) {
@@ -624,6 +633,8 @@ static WERROR srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_
int i;
struct srvsvc_NetShareCtr2 *ctr2;
+ SRVSVC_CHECK_ADMIN_ACCESS;
+
ctr2 = talloc(mem_ctx, struct srvsvc_NetShareCtr2);
W_ERROR_HAVE_NO_MEMORY(ctr2);
@@ -658,6 +669,8 @@ static WERROR srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_
int i;
struct srvsvc_NetShareCtr501 *ctr501;
+ SRVSVC_CHECK_ADMIN_ACCESS;
+
ctr501 = talloc(mem_ctx, struct srvsvc_NetShareCtr501);
W_ERROR_HAVE_NO_MEMORY(ctr501);
@@ -692,6 +705,8 @@ static WERROR srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_
int i;
struct srvsvc_NetShareCtr502 *ctr502;
+ SRVSVC_CHECK_ADMIN_ACCESS;
+
ctr502 = talloc(mem_ctx, struct srvsvc_NetShareCtr502);
W_ERROR_HAVE_NO_MEMORY(ctr502);
@@ -789,6 +804,8 @@ static WERROR srvsvc_NetShareGetInfo(struct dcesrv_call_state *dce_call, TALLOC_
WERROR status;
union srvsvc_NetShareInfo info;
+ SRVSVC_CHECK_ADMIN_ACCESS;
+
info.info2 = talloc(mem_ctx, struct srvsvc_NetShareInfo2);
W_ERROR_HAVE_NO_MEMORY(info.info2);
@@ -821,6 +838,8 @@ static WERROR srvsvc_NetShareGetInfo(struct dcesrv_call_state *dce_call, TALLOC_
WERROR status;
union srvsvc_NetShareInfo info;
+ SRVSVC_CHECK_ADMIN_ACCESS;
+
info.info502 = talloc(mem_ctx, struct srvsvc_NetShareInfo502);
W_ERROR_HAVE_NO_MEMORY(info.info502);
@@ -1171,7 +1190,190 @@ static WERROR srvsvc_NetPRNameCompare(struct dcesrv_call_state *dce_call, TALLOC
static WERROR srvsvc_NetShareEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct srvsvc_NetShareEnum *r)
{
- DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+ struct dcesrv_context *dce_ctx = dce_call->conn->dce_ctx;
+
+ r->out.level = r->in.level;
+ ZERO_STRUCT(r->out.ctr);
+ r->out.totalentries = 0;
+ r->out.resume_handle = NULL;
+
+ /* TODO: - paging of results
+ */
+
+ switch (r->in.level) {
+ case 0:
+ {
+ int i, y = 0;
+ int count;
+ struct srvsvc_NetShareCtr0 *ctr0;
+
+ ctr0 = talloc(mem_ctx, struct srvsvc_NetShareCtr0);
+ W_ERROR_HAVE_NO_MEMORY(ctr0);
+
+ count = dcesrv_common_get_count_of_shares(mem_ctx, dce_ctx);
+ ctr0->count = count;
+ ctr0->array = NULL;
+
+ if (ctr0->count == 0) {
+ r->out.ctr.ctr0 = ctr0;
+ return WERR_OK;
+ }
+
+ ctr0->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo0, count);
+ W_ERROR_HAVE_NO_MEMORY(ctr0->array);
+
+ for (i=0; i < count; i++) {
+ WERROR status;
+ union srvsvc_NetShareInfo info;
+ enum srvsvc_ShareType type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, i);
+
+ if (type & STYPE_HIDDEN) {
+ ctr0->count--;
+ continue;
+ }
+
+ info.info0 = &ctr0->array[y];
+ status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, i, r->in.level, &info);
+ W_ERROR_NOT_OK_RETURN(status);
+ y++;
+ }
+
+ r->out.ctr.ctr0 = ctr0;
+ r->out.totalentries = r->out.ctr.ctr0->count;
+ return WERR_OK;
+ }
+ case 1:
+ {
+ int i, y = 0;
+ int count;
+ struct srvsvc_NetShareCtr1 *ctr1;
+
+ ctr1 = talloc(mem_ctx, struct srvsvc_NetShareCtr1);
+ W_ERROR_HAVE_NO_MEMORY(ctr1);
+
+ count = dcesrv_common_get_count_of_shares(mem_ctx, dce_ctx);
+ ctr1->count = count;
+ ctr1->array = NULL;
+
+ if (ctr1->count == 0) {
+ r->out.ctr.ctr1 = ctr1;
+ return WERR_OK;
+ }
+
+ ctr1->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo1, count);
+ W_ERROR_HAVE_NO_MEMORY(ctr1->array);
+
+ for (i=0; i < count; i++) {
+ WERROR status;
+ union srvsvc_NetShareInfo info;
+ enum srvsvc_ShareType type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, i);
+
+ if (type & STYPE_HIDDEN) {
+ ctr1->count--;
+ continue;
+ }
+
+ info.info1 = &ctr1->array[y];
+ status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, i, r->in.level, &info);
+ W_ERROR_NOT_OK_RETURN(status);
+ y++;
+ }
+
+ r->out.ctr.ctr1 = ctr1;
+ r->out.totalentries = r->out.ctr.ctr1->count;
+ return WERR_OK;
+ }
+ case 2:
+ {
+ int i, y = 0;
+ int count;
+ struct srvsvc_NetShareCtr2 *ctr2;
+
+ SRVSVC_CHECK_ADMIN_ACCESS;
+
+ ctr2 = talloc(mem_ctx, struct srvsvc_NetShareCtr2);
+ W_ERROR_HAVE_NO_MEMORY(ctr2);
+
+ count = dcesrv_common_get_count_of_shares(mem_ctx, dce_ctx);
+ ctr2->count = count;
+ ctr2->array = NULL;
+
+ if (ctr2->count == 0) {
+ r->out.ctr.ctr2 = ctr2;
+ return WERR_OK;
+ }
+
+ ctr2->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo2, count);
+ W_ERROR_HAVE_NO_MEMORY(ctr2->array);
+
+ for (i=0; i < count; i++) {
+ WERROR status;
+ union srvsvc_NetShareInfo info;
+ enum srvsvc_ShareType type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, i);
+
+ if (type & STYPE_HIDDEN) {
+ ctr2->count--;
+ continue;
+ }
+
+ info.info2 = &ctr2->array[y];
+ status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, i, r->in.level, &info);
+ W_ERROR_NOT_OK_RETURN(status);
+ y++;
+ }
+
+ r->out.ctr.ctr2 = ctr2;
+ r->out.totalentries = r->out.ctr.ctr2->count;
+ return WERR_OK;
+ }
+ case 502:
+ {
+ int i, y = 0;
+ int count;
+ struct srvsvc_NetShareCtr502 *ctr502;
+
+ SRVSVC_CHECK_ADMIN_ACCESS;
+
+ ctr502 = talloc(mem_ctx, struct srvsvc_NetShareCtr502);
+ W_ERROR_HAVE_NO_MEMORY(ctr502);
+
+ count = dcesrv_common_get_count_of_shares(mem_ctx, dce_ctx);
+ ctr502->count = count;
+ ctr502->array = NULL;
+
+ if (ctr502->count == 0) {
+ r->out.ctr.ctr502 = ctr502;
+ return WERR_OK;
+ }
+
+ ctr502->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo502, count);
+ W_ERROR_HAVE_NO_MEMORY(ctr502->array);
+
+ for (i=0; i < count; i++) {
+ WERROR status;
+ union srvsvc_NetShareInfo info;
+ enum srvsvc_ShareType type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, i);
+
+ if (type & STYPE_HIDDEN) {
+ ctr502->count--;
+ continue;
+ }
+
+ info.info502 = &ctr502->array[y];
+ status = srvsvc_fiel_ShareInfo(dce_call, mem_ctx, i, r->in.level, &info);
+ W_ERROR_NOT_OK_RETURN(status);
+ y++;
+ }
+
+ r->out.ctr.ctr502 = ctr502;
+ r->out.totalentries = r->out.ctr.ctr502->count;
+ return WERR_OK;
+ }
+ default:
+ return WERR_UNKNOWN_LEVEL;
+ }
+
+ return WERR_UNKNOWN_LEVEL;
}