diff options
author | Andrew Tridgell <tridge@samba.org> | 2004-05-03 14:58:08 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:51:44 -0500 |
commit | 8db18a0775a66ee3073484b987d4a9ff0fd22c90 (patch) | |
tree | 59d206db21060a70fc90f9d1e3b4dca8d1ebd211 /source4/rpc_server | |
parent | af48da52bf39f8055b6f1640bcadeb27aeaead2d (diff) | |
download | samba-8db18a0775a66ee3073484b987d4a9ff0fd22c90.tar.gz samba-8db18a0775a66ee3073484b987d4a9ff0fd22c90.tar.bz2 samba-8db18a0775a66ee3073484b987d4a9ff0fd22c90.zip |
r458: this is the (very primitive) beginnings of a SAMR server for
Samba4. I'm committing this now so I can get comments on the approach.
Note that you need to do something like this to initialise the SAM db:
edit script/provision.pl
script/provision.pl > provision.ldif.out
bin/ldbadd /path/to/private/sam.ldb provision.ldif.out
(This used to be commit e2002e40a5abe0cd33a2056b1da8ba5732f9021f)
Diffstat (limited to 'source4/rpc_server')
-rw-r--r-- | source4/rpc_server/config.m4 | 1 | ||||
-rw-r--r-- | source4/rpc_server/samr/dcesrv_samr.c | 933 | ||||
-rw-r--r-- | source4/rpc_server/samr/samdb.c | 189 |
3 files changed, 1123 insertions, 0 deletions
diff --git a/source4/rpc_server/config.m4 b/source4/rpc_server/config.m4 index eeecc7642f..09e76c2ead 100644 --- a/source4/rpc_server/config.m4 +++ b/source4/rpc_server/config.m4 @@ -8,6 +8,7 @@ SMB_MODULE(dcerpc_epmapper,DCERPC,STATIC,[rpc_server/epmapper/rpc_epmapper.o]) SMB_MODULE(dcerpc_remote,DCERPC,STATIC,[rpc_server/remote/dcesrv_remote.o]) SMB_MODULE(dcerpc_srvsvc,DCERPC,STATIC,[rpc_server/srvsvc/dcesrv_srvsvc.o]) SMB_MODULE(dcerpc_wkssvc,DCERPC,STATIC,[rpc_server/wkssvc/dcesrv_wkssvc.o]) +SMB_MODULE(dcerpc_samr,DCERPC,STATIC,[rpc_server/samr/dcesrv_samr.o rpc_server/samr/samdb.o]) SMB_MODULE(dcerpc_winreg,DCERPC,STATIC,[rpc_server/winreg/rpc_winreg.o \$(REG_OBJS)],[],[\$(REG_LIBS)]) SMB_SUBSYSTEM(DCERPC,rpc_server/dcerpc_server.o, diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c new file mode 100644 index 0000000000..e4dcf398a2 --- /dev/null +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -0,0 +1,933 @@ +/* + Unix SMB/CIFS implementation. + + endpoint server for the samr pipe + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* + this type allows us to distinguish handle types +*/ +enum samr_handle { + SAMR_HANDLE_CONNECT, + SAMR_HANDLE_DOMAIN, + SAMR_HANDLE_USER, + SAMR_HANDLE_GROUP, + SAMR_HANDLE_ALIAS +}; + + +/* + state asscoiated with a samr_Connect*() operation +*/ +struct samr_connect_state { + TALLOC_CTX *mem_ctx; + uint32 access_mask; +}; + + +/* + destroy an open connection. This closes the database connection +*/ +static void samr_Connect_destroy(struct dcesrv_connection *conn, struct dcesrv_handle *h) +{ + struct samr_connect_state *state = h->data; + talloc_destroy(state->mem_ctx); +} + +/* + samr_Connect + + create a connection to the SAM database +*/ +static NTSTATUS samr_Connect(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_Connect *r) +{ + struct samr_connect_state *state; + struct dcesrv_handle *handle; + TALLOC_CTX *connect_mem_ctx; + + ZERO_STRUCTP(r->out.handle); + + connect_mem_ctx = talloc_init("samr_Connect"); + if (!connect_mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + state = talloc_p(connect_mem_ctx, struct samr_connect_state); + if (!state) { + return NT_STATUS_NO_MEMORY; + } + state->mem_ctx = connect_mem_ctx; + + /* make sure the sam database is accessible */ + if (samdb_connect() != 0) { + r->out.result = NT_STATUS_INVALID_SYSTEM_SERVICE; + talloc_destroy(state->mem_ctx); + return NT_STATUS_OK; + } + + handle = dcesrv_handle_new(dce_call->conn, SAMR_HANDLE_CONNECT); + if (!handle) { + talloc_destroy(state->mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + handle->data = state; + handle->destroy = samr_Connect_destroy; + + state->access_mask = r->in.access_mask; + *r->out.handle = handle->wire_handle; + r->out.result = NT_STATUS_OK; + + return NT_STATUS_OK; +} + + +/* + samr_Close +*/ +static NTSTATUS samr_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_Close *r) +{ + struct dcesrv_handle *h = dcesrv_handle_fetch(dce_call->conn, + r->in.handle, + DCESRV_HANDLE_ANY); + if (!h) { + return NT_STATUS_INVALID_HANDLE; + } + + /* this causes the callback samr_XXX_destroy() to be called by + the handle destroy code which destroys the state associated + with the handle */ + dcesrv_handle_destroy(dce_call->conn, h); + + r->out.result = NT_STATUS_OK; + ZERO_STRUCTP(r->out.handle); + + return NT_STATUS_OK; +} + + +/* + samr_SetSecurity +*/ +static NTSTATUS samr_SetSecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_SetSecurity *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_QuerySecurity +*/ +static NTSTATUS samr_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_QuerySecurity *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_Shutdown + + we refuse this operation completely. If a admin wants to shutdown samr + in Samba then they should use the samba admin tools to disable the samr pipe +*/ +static NTSTATUS samr_Shutdown(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_Shutdown *r) +{ + return NT_STATUS_ACCESS_DENIED; +} + + +/* + samr_LookupDomain + + this maps from a domain name to a SID +*/ +static NTSTATUS samr_LookupDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_LookupDomain *r) +{ + struct dcesrv_handle *h; + struct dom_sid2 *sid; + const char *sidstr; + + h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, SAMR_HANDLE_CONNECT); + if (!h) { + return NT_STATUS_INVALID_HANDLE; + } + + r->out.sid = NULL; + + if (r->in.domain->name == NULL) { + r->out.result = NT_STATUS_INVALID_PARAMETER; + return NT_STATUS_OK; + } + + sidstr = samdb_search_string(mem_ctx, "objectSid", + "(&(name=%s)(objectclass=domain))", + r->in.domain->name); + if (sidstr == NULL) { + r->out.result = NT_STATUS_NO_SUCH_DOMAIN; + return NT_STATUS_OK; + } + + sid = dom_sid_parse_talloc(mem_ctx, sidstr); + if (sid == NULL) { + DEBUG(1,("samdb: Invalid sid '%s' for domain %s\n", + sidstr, r->in.domain->name)); + r->out.result = NT_STATUS_INTERNAL_DB_CORRUPTION; + return NT_STATUS_OK; + } + + r->out.sid = sid; + r->out.result = NT_STATUS_OK; + + return NT_STATUS_OK; +} + + +/* + samr_EnumDomains + + list the domains in the SAM +*/ +static NTSTATUS samr_EnumDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_EnumDomains *r) +{ + struct dcesrv_handle *h; + struct samr_SamArray *array; + char **domains; + int count, i, start_i; + + h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, SAMR_HANDLE_CONNECT); + if (!h) { + return NT_STATUS_INVALID_HANDLE; + } + + *r->out.resume_handle = 0; + r->out.sam = NULL; + r->out.num_entries = 0; + + count = samdb_search_string_multiple(mem_ctx, &domains, + "name", "(objectclass=domain)"); + if (count == -1) { + DEBUG(1,("samdb: no domains found in EnumDomains\n")); + r->out.result = NT_STATUS_INTERNAL_DB_CORRUPTION; + return NT_STATUS_OK; + } + + *r->out.resume_handle = count; + + start_i = *r->in.resume_handle; + + if (start_i >= count) { + /* search past end of list is not an error for this call */ + r->out.result = NT_STATUS_OK; + return NT_STATUS_OK; + } + + array = talloc_p(mem_ctx, struct samr_SamArray); + if (array == NULL) { + r->out.result = NT_STATUS_NO_MEMORY; + return NT_STATUS_OK; + } + + array->count = 0; + array->entries = NULL; + + array->entries = talloc_array_p(mem_ctx, struct samr_SamEntry, count - start_i); + if (array->entries == NULL) { + r->out.result = NT_STATUS_NO_MEMORY; + return NT_STATUS_OK; + } + + for (i=0;i<count-start_i;i++) { + array->entries[i].idx = start_i + i; + array->entries[i].name.name = domains[start_i+i]; + } + + r->out.sam = array; + r->out.num_entries = i - start_i; + array->count = r->out.num_entries; + r->out.result = NT_STATUS_OK; + + return NT_STATUS_OK; +} + + +/* + samr_OpenDomain +*/ +static NTSTATUS samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_OpenDomain *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_QueryDomainInfo +*/ +static NTSTATUS samr_QueryDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_QueryDomainInfo *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_SetDomainInfo +*/ +static NTSTATUS samr_SetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_SetDomainInfo *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_CreateDomainGroup +*/ +static NTSTATUS samr_CreateDomainGroup(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_CreateDomainGroup *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_EnumDomainGroups +*/ +static NTSTATUS samr_EnumDomainGroups(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_EnumDomainGroups *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_CreateUser +*/ +static NTSTATUS samr_CreateUser(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_CreateUser *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_EnumDomainUsers +*/ +static NTSTATUS samr_EnumDomainUsers(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_EnumDomainUsers *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_CreateDomAlias +*/ +static NTSTATUS samr_CreateDomAlias(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_CreateDomAlias *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_EnumDomainAliases +*/ +static NTSTATUS samr_EnumDomainAliases(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_EnumDomainAliases *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_GetAliasMembership +*/ +static NTSTATUS samr_GetAliasMembership(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_GetAliasMembership *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_LookupNames +*/ +static NTSTATUS samr_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_LookupNames *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_LookupRids +*/ +static NTSTATUS samr_LookupRids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_LookupRids *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_OpenGroup +*/ +static NTSTATUS samr_OpenGroup(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_OpenGroup *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_QueryGroupInfo +*/ +static NTSTATUS samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_QueryGroupInfo *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_SetGroupInfo +*/ +static NTSTATUS samr_SetGroupInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_SetGroupInfo *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_AddGroupMember +*/ +static NTSTATUS samr_AddGroupMember(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_AddGroupMember *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_DeleteDomainGroup +*/ +static NTSTATUS samr_DeleteDomainGroup(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_DeleteDomainGroup *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_DeleteGroupMember +*/ +static NTSTATUS samr_DeleteGroupMember(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_DeleteGroupMember *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_QueryGroupMember +*/ +static NTSTATUS samr_QueryGroupMember(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_QueryGroupMember *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_SetMemberAttributesOfGroup +*/ +static NTSTATUS samr_SetMemberAttributesOfGroup(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_SetMemberAttributesOfGroup *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_OpenAlias +*/ +static NTSTATUS samr_OpenAlias(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_OpenAlias *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_QueryAliasInfo +*/ +static NTSTATUS samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_QueryAliasInfo *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_SetAliasInfo +*/ +static NTSTATUS samr_SetAliasInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_SetAliasInfo *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_DeleteDomAlias +*/ +static NTSTATUS samr_DeleteDomAlias(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_DeleteDomAlias *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_AddAliasMember +*/ +static NTSTATUS samr_AddAliasMember(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_AddAliasMember *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_DeleteAliasMember +*/ +static NTSTATUS samr_DeleteAliasMember(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_DeleteAliasMember *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_GetMembersInAlias +*/ +static NTSTATUS samr_GetMembersInAlias(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_GetMembersInAlias *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_OpenUser +*/ +static NTSTATUS samr_OpenUser(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_OpenUser *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_DeleteUser +*/ +static NTSTATUS samr_DeleteUser(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_DeleteUser *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_QueryUserInfo +*/ +static NTSTATUS samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_QueryUserInfo *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_SetUserInfo +*/ +static NTSTATUS samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_SetUserInfo *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_ChangePasswordUser +*/ +static NTSTATUS samr_ChangePasswordUser(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_ChangePasswordUser *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_GetGroupsForUser +*/ +static NTSTATUS samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_GetGroupsForUser *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_QueryDisplayInfo +*/ +static NTSTATUS samr_QueryDisplayInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_QueryDisplayInfo *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_GetDisplayEnumerationIndex +*/ +static NTSTATUS samr_GetDisplayEnumerationIndex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_GetDisplayEnumerationIndex *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_TestPrivateFunctionsDomain +*/ +static NTSTATUS samr_TestPrivateFunctionsDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_TestPrivateFunctionsDomain *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_TestPrivateFunctionsUser +*/ +static NTSTATUS samr_TestPrivateFunctionsUser(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_TestPrivateFunctionsUser *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_GetUserPwInfo +*/ +static NTSTATUS samr_GetUserPwInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_GetUserPwInfo *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_RemoveMemberFromForeignDomain +*/ +static NTSTATUS samr_RemoveMemberFromForeignDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_RemoveMemberFromForeignDomain *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_QueryDomainInfo2 +*/ +static NTSTATUS samr_QueryDomainInfo2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_QueryDomainInfo2 *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_QueryUserInfo2 +*/ +static NTSTATUS samr_QueryUserInfo2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_QueryUserInfo2 *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_QueryDisplayInfo2 +*/ +static NTSTATUS samr_QueryDisplayInfo2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_QueryDisplayInfo2 *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_GetDisplayEnumerationIndex2 +*/ +static NTSTATUS samr_GetDisplayEnumerationIndex2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_GetDisplayEnumerationIndex2 *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_CreateUser2 +*/ +static NTSTATUS samr_CreateUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_CreateUser2 *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_QueryDisplayInfo3 +*/ +static NTSTATUS samr_QueryDisplayInfo3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_QueryDisplayInfo3 *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_AddMultipleMembersToAlias +*/ +static NTSTATUS samr_AddMultipleMembersToAlias(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_AddMultipleMembersToAlias *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_RemoveMultipleMembersFromAlias +*/ +static NTSTATUS samr_RemoveMultipleMembersFromAlias(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_RemoveMultipleMembersFromAlias *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_OemChangePasswordUser2 +*/ +static NTSTATUS samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_OemChangePasswordUser2 *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_ChangePasswordUser2 +*/ +static NTSTATUS samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_ChangePasswordUser2 *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_GetDomPwInfo +*/ +static NTSTATUS samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_GetDomPwInfo *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_Connect2 +*/ +static NTSTATUS samr_Connect2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_Connect2 *r) +{ + struct samr_Connect c; + NTSTATUS status; + + c.in.system_name = NULL; + c.in.access_mask = r->in.access_mask; + c.out.handle = r->out.handle; + + status = samr_Connect(dce_call, mem_ctx, &c); + r->out.result = c.out.result; + + return status; +} + + +/* + samr_SetUserInfo2 +*/ +static NTSTATUS samr_SetUserInfo2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_SetUserInfo2 *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_SetBootKeyInformation +*/ +static NTSTATUS samr_SetBootKeyInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_SetBootKeyInformation *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_GetBootKeyInformation +*/ +static NTSTATUS samr_GetBootKeyInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_GetBootKeyInformation *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_Connect3 +*/ +static NTSTATUS samr_Connect3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_Connect3 *r) +{ + struct samr_Connect c; + NTSTATUS status; + + c.in.system_name = NULL; + c.in.access_mask = r->in.access_mask; + c.out.handle = r->out.handle; + + status = samr_Connect(dce_call, mem_ctx, &c); + r->out.result = c.out.result; + + return status; +} + + +/* + samr_Connect4 +*/ +static NTSTATUS samr_Connect4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_Connect4 *r) +{ + struct samr_Connect c; + NTSTATUS status; + + c.in.system_name = NULL; + c.in.access_mask = r->in.access_mask; + c.out.handle = r->out.handle; + + status = samr_Connect(dce_call, mem_ctx, &c); + r->out.result = c.out.result; + + return status; +} + + +/* + samr_ChangePasswordUser3 +*/ +static NTSTATUS samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_ChangePasswordUser3 *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_Connect5 +*/ +static NTSTATUS samr_Connect5(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_Connect5 *r) +{ + struct samr_Connect c; + NTSTATUS status; + + c.in.system_name = NULL; + c.in.access_mask = r->in.access_mask; + c.out.handle = r->out.handle; + + status = samr_Connect(dce_call, mem_ctx, &c); + + r->out.info->info1.unknown1 = 3; + r->out.info->info1.unknown2 = 0; + r->out.level = r->in.level; + r->out.result = c.out.result; + + return status; +} + + +/* + samr_RidToSid +*/ +static NTSTATUS samr_RidToSid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_RidToSid *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_SetDsrmPassword +*/ +static NTSTATUS samr_SetDsrmPassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_SetDsrmPassword *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + samr_ValidatePassword +*/ +static NTSTATUS samr_ValidatePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct samr_ValidatePassword *r) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* include the generated boilerplate */ +#include "librpc/gen_ndr/ndr_samr_s.c" diff --git a/source4/rpc_server/samr/samdb.c b/source4/rpc_server/samr/samdb.c new file mode 100644 index 0000000000..ac58fe2c01 --- /dev/null +++ b/source4/rpc_server/samr/samdb.c @@ -0,0 +1,189 @@ +/* + Unix SMB/CIFS implementation. + + interface functions for the sam database + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + + +/* + the way that unix fcntl locking works forces us to have a static ldb + handle here rather than a much more sensible approach of having the + ldb handle as part of the samr_Connect() pipe state. Otherwise we + would try to open the ldb more than once, and tdb would rightly + refuse the second open due to the broken nature of unix locking. +*/ +static struct ldb_context *sam_db; + +/* + connect to the SAM database + return 0 on success, -1 on failure + */ +int samdb_connect(void) +{ + if (sam_db != NULL) { + return 0; + } + sam_db = ldb_connect(lp_sam_url(), 0, NULL); + + if (sam_db == NULL) { + return -1; + } + + return 0; +} + + +/* + search the sam for the specified attributes - va_list varient +*/ +int samdb_search_v(struct ldb_message ***res, + const char * const *attrs, + const char *format, + va_list ap) +{ + char *expr = NULL; + int count; + + vasprintf(&expr, format, ap); + if (expr == NULL) { + return -1; + } + + count = ldb_search(sam_db, NULL, LDB_SCOPE_SUBTREE, expr, attrs, res); + + free(expr); + + return count; +} + + +/* + search the sam for the specified attributes - varargs varient +*/ +int samdb_search(struct ldb_message ***res, + const char * const *attrs, + const char *format, ...) +{ + va_list ap; + int count; + + va_start(ap, format); + count = samdb_search_v(res, attrs, format, ap); + va_end(ap); + + return count; +} + + +/* + search the sam for a single string attribute in exactly 1 record +*/ +const char *samdb_search_string(TALLOC_CTX *mem_ctx, + const char *attr_name, + const char *format, ...) +{ + va_list ap; + int count; + const char * const attrs[2] = { attr_name, NULL }; + struct ldb_message **res = NULL; + const char *str = NULL; + + va_start(ap, format); + count = samdb_search_v(&res, attrs, format, ap); + va_end(ap); + + if (count == 0) { + return NULL; + } + + /* make sure its single valued */ + if (count != 1 || + res[0]->num_elements != 1 || + res[0]->elements[0].num_values != 1 || + res[0]->elements[0].values[0].data == NULL) { + DEBUG(1,("samdb: search for %s %s not single valued\n", + attr_name, format)); + ldb_search_free(sam_db, res); + return NULL; + } + + str = talloc_strndup(mem_ctx, + res[0]->elements[0].values[0].data, + res[0]->elements[0].values[0].length); + + ldb_search_free(sam_db, res); + + return str; +} + + +/* + search the sam for multipe records each giving a single string attribute + return the number of matches, or -1 on error +*/ +int samdb_search_string_multiple(TALLOC_CTX *mem_ctx, + char ***strs, + const char *attr_name, + const char *format, ...) +{ + va_list ap; + int count, i; + const char * const attrs[2] = { attr_name, NULL }; + struct ldb_message **res = NULL; + + va_start(ap, format); + count = samdb_search_v(&res, attrs, format, ap); + va_end(ap); + + if (count <= 0) { + return count; + } + + /* make sure its single valued */ + for (i=0;i<count;i++) { + if (res[i]->num_elements != 1 || + res[i]->elements[0].num_values != 1 || + res[i]->elements[0].values[0].data == NULL) { + DEBUG(1,("samdb: search for %s %s not single valued\n", + attr_name, format)); + ldb_search_free(sam_db, res); + return -1; + } + } + + *strs = talloc_array_p(mem_ctx, char *, count+1); + if (! *strs) { + ldb_search_free(sam_db, res); + return -1; + } + + for (i=0;i<count;i++) { + (*strs)[i] = talloc_strndup(mem_ctx, + res[i]->elements[0].values[0].data, + res[i]->elements[0].values[0].length); + } + (*strs)[count] = NULL; + + ldb_search_free(sam_db, res); + + return count; +} + |