summaryrefslogtreecommitdiff
path: root/source3/rpc_server
diff options
context:
space:
mode:
Diffstat (limited to 'source3/rpc_server')
-rw-r--r--source3/rpc_server/srv_lsa.c190
-rw-r--r--source3/rpc_server/srv_lsa_nt.c217
2 files changed, 406 insertions, 1 deletions
diff --git a/source3/rpc_server/srv_lsa.c b/source3/rpc_server/srv_lsa.c
index 005398924e..9c934f5023 100644
--- a/source3/rpc_server/srv_lsa.c
+++ b/source3/rpc_server/srv_lsa.c
@@ -269,6 +269,96 @@ static BOOL api_lsa_open_secret(pipes_struct *p)
}
/***************************************************************************
+ api_lsa_open_secret.
+ ***************************************************************************/
+
+static BOOL api_lsa_enum_privs(pipes_struct *p)
+{
+ LSA_Q_ENUM_PRIVS q_u;
+ LSA_R_ENUM_PRIVS r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!lsa_io_q_enum_privs("", &q_u, data, 0)) {
+ DEBUG(0,("api_lsa_enum_privs: failed to unmarshall LSA_Q_ENUM_PRIVS.\n"));
+ return False;
+ }
+
+ r_u.status = _lsa_enum_privs(p, &q_u, &r_u);
+
+ /* store the response in the SMB stream */
+ if(!lsa_io_r_enum_privs("", &r_u, rdata, 0)) {
+ DEBUG(0,("api_lsa_enum_privs: Failed to marshall LSA_R_ENUM_PRIVS.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/***************************************************************************
+ api_lsa_open_secret.
+ ***************************************************************************/
+
+static BOOL api_lsa_priv_get_dispname(pipes_struct *p)
+{
+ LSA_Q_PRIV_GET_DISPNAME q_u;
+ LSA_R_PRIV_GET_DISPNAME r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!lsa_io_q_priv_get_dispname("", &q_u, data, 0)) {
+ DEBUG(0,("api_lsa_priv_get_dispname: failed to unmarshall LSA_Q_PRIV_GET_DISPNAME.\n"));
+ return False;
+ }
+
+ r_u.status = _lsa_priv_get_dispname(p, &q_u, &r_u);
+
+ /* store the response in the SMB stream */
+ if(!lsa_io_r_priv_get_dispname("", &r_u, rdata, 0)) {
+ DEBUG(0,("api_lsa_priv_get_dispname: Failed to marshall LSA_R_PRIV_GET_DISPNAME.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/***************************************************************************
+ api_lsa_open_secret.
+ ***************************************************************************/
+
+static BOOL api_lsa_enum_accounts(pipes_struct *p)
+{
+ LSA_Q_ENUM_ACCOUNTS q_u;
+ LSA_R_ENUM_ACCOUNTS r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!lsa_io_q_enum_accounts("", &q_u, data, 0)) {
+ DEBUG(0,("api_lsa_enum_accounts: failed to unmarshall LSA_Q_ENUM_ACCOUNTS.\n"));
+ return False;
+ }
+
+ r_u.status = _lsa_enum_accounts(p, &q_u, &r_u);
+
+ /* store the response in the SMB stream */
+ if(!lsa_io_r_enum_accounts("", &r_u, rdata, 0)) {
+ DEBUG(0,("api_lsa_enum_accounts: Failed to marshall LSA_R_ENUM_ACCOUNTS.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/***************************************************************************
api_lsa_UNK_GET_CONNUSER
***************************************************************************/
@@ -300,6 +390,100 @@ static BOOL api_lsa_unk_get_connuser(pipes_struct *p)
}
/***************************************************************************
+ api_lsa_open_user
+ ***************************************************************************/
+
+static BOOL api_lsa_open_account(pipes_struct *p)
+{
+ LSA_Q_OPENACCOUNT q_u;
+ LSA_R_OPENACCOUNT r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!lsa_io_q_open_account("", &q_u, data, 0)) {
+ DEBUG(0,("api_lsa_open_account: failed to unmarshall LSA_Q_OPENACCOUNT.\n"));
+ return False;
+ }
+
+ r_u.status = _lsa_open_account(p, &q_u, &r_u);
+
+ /* store the response in the SMB stream */
+ if(!lsa_io_r_open_account("", &r_u, rdata, 0)) {
+ DEBUG(0,("api_lsa_open_account: Failed to marshall LSA_R_OPENACCOUNT.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/***************************************************************************
+ api_lsa_get_privs
+ ***************************************************************************/
+
+static BOOL api_lsa_enum_privsaccount(pipes_struct *p)
+{
+ LSA_Q_ENUMPRIVSACCOUNT q_u;
+ LSA_R_ENUMPRIVSACCOUNT r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!lsa_io_q_enum_privsaccount("", &q_u, data, 0)) {
+ DEBUG(0,("api_lsa_enum_privsaccount: failed to unmarshall LSA_Q_ENUMPRIVSACCOUNT.\n"));
+ return False;
+ }
+
+ r_u.status = _lsa_enum_privsaccount(p, &q_u, &r_u);
+
+ /* store the response in the SMB stream */
+ if(!lsa_io_r_enum_privsaccount("", &r_u, rdata, 0)) {
+ DEBUG(0,("api_lsa_enum_privsaccount: Failed to marshall LSA_R_ENUMPRIVSACCOUNT.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/***************************************************************************
+ api_lsa_getsystemaccount
+ ***************************************************************************/
+
+static BOOL api_lsa_getsystemaccount(pipes_struct *p)
+{
+ LSA_Q_GETSYSTEMACCOUNT q_u;
+ LSA_R_GETSYSTEMACCOUNT r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!lsa_io_q_getsystemaccount("", &q_u, data, 0)) {
+ DEBUG(0,("api_lsa_getsystemaccount: failed to unmarshall LSA_Q_GETSYSTEMACCOUNT.\n"));
+ return False;
+ }
+
+ r_u.status = _lsa_getsystemaccount(p, &q_u, &r_u);
+
+ /* store the response in the SMB stream */
+ if(!lsa_io_r_getsystemaccount("", &r_u, rdata, 0)) {
+ DEBUG(0,("api_lsa_getsystemaccount: Failed to marshall LSA_R_GETSYSTEMACCOUNT.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+
+/***************************************************************************
\PIPE\ntlsa commands
***************************************************************************/
@@ -313,7 +497,13 @@ static struct api_struct api_lsa_cmds[] =
{ "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret },
{ "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS , api_lsa_lookup_sids },
{ "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES , api_lsa_lookup_names },
+ { "LSA_ENUM_PRIVS" , LSA_ENUM_PRIVS , api_lsa_enum_privs },
+ { "LSA_PRIV_GET_DISPNAME",LSA_PRIV_GET_DISPNAME,api_lsa_priv_get_dispname},
+ { "LSA_ENUM_ACCOUNTS" , LSA_ENUM_ACCOUNTS , api_lsa_enum_accounts },
{ "LSA_UNK_GET_CONNUSER", LSA_UNK_GET_CONNUSER, api_lsa_unk_get_connuser},
+ { "LSA_OPENACCOUNT" , LSA_OPENACCOUNT , api_lsa_open_account },
+ { "LSA_ENUMPRIVSACCOUNT", LSA_ENUMPRIVSACCOUNT, api_lsa_enum_privsaccount},
+ { "LSA_GETSYSTEMACCOUNT", LSA_GETSYSTEMACCOUNT, api_lsa_getsystemaccount},
{ NULL , 0 , NULL }
};
diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c
index cd97dfc6d1..85bab7d4b0 100644
--- a/source3/rpc_server/srv_lsa_nt.c
+++ b/source3/rpc_server/srv_lsa_nt.c
@@ -30,6 +30,23 @@ extern int DEBUGLEVEL;
extern DOM_SID global_sam_sid;
extern fstring global_myworkgroup;
extern pstring global_myname;
+extern PRIVS privs[];
+
+struct lsa_info {
+ DOM_SID sid;
+ uint32 access;
+};
+
+/*******************************************************************
+ Function to free the per handle data.
+ ********************************************************************/
+
+static void free_lsa_info(void *ptr)
+{
+ struct lsa_info *lsa = (struct lsa_info *)ptr;
+
+ safe_free(lsa);
+}
/***************************************************************************
Init dom_query
@@ -128,7 +145,7 @@ static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
/* Split name into domain and user component */
- rpcstr_pull(full_name, &name[i], sizeof(full_name), -1, 0);
+ unistr2_to_ascii(full_name, &name[i], sizeof(full_name));
split_domain_name(full_name, dom_name, user);
/* Lookup name */
@@ -511,6 +528,116 @@ uint32 _lsa_open_secret(pipes_struct *p, LSA_Q_OPEN_SECRET *q_u, LSA_R_OPEN_SECR
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
+/***************************************************************************
+_lsa_enum_privs.
+ ***************************************************************************/
+
+uint32 _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIVS *r_u)
+{
+ uint32 i;
+
+ uint32 enum_context=q_u->enum_context;
+ LSA_PRIV_ENTRY *entry;
+ LSA_PRIV_ENTRY *entries;
+
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
+ return NT_STATUS_INVALID_HANDLE;
+
+ if (enum_context >= PRIV_ALL_INDEX)
+ return 0x8000001A;
+
+ entries = (LSA_PRIV_ENTRY *)talloc_zero(p->mem_ctx, sizeof(LSA_PRIV_ENTRY) * (PRIV_ALL_INDEX-enum_context));
+ if (entries==NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ entry = entries;
+ for (i = 0; i < PRIV_ALL_INDEX-enum_context; i++, entry++) {
+ init_uni_hdr(&entry->hdr_name, strlen(privs[i+1-enum_context].priv));
+ init_unistr2(&entry->name, privs[i+1-enum_context].priv, strlen(privs[i+1-enum_context].priv) );
+ entry->luid_low = privs[i+1-enum_context].se_priv;
+ entry->luid_high = 1;
+ }
+
+ init_lsa_r_enum_privs(r_u, i+enum_context, PRIV_ALL_INDEX-enum_context, entries);
+
+ return NT_STATUS_NO_PROBLEMO;
+}
+
+/***************************************************************************
+_lsa_priv_get_dispname.
+ ***************************************************************************/
+
+uint32 _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, LSA_R_PRIV_GET_DISPNAME *r_u)
+{
+ fstring name_asc;
+ fstring desc_asc;
+ int i;
+
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
+ return NT_STATUS_INVALID_HANDLE;
+
+ unistr2_to_ascii(name_asc, &q_u->name, sizeof(name_asc));
+
+ DEBUG(0,("_lsa_priv_get_dispname: %s", name_asc));
+
+ for (i=1; privs[i].se_priv!=SE_PRIV_ALL; i++) {
+ if ( strcmp(name_asc, privs[i].priv)) {
+
+ fstrcpy(desc_asc, privs[i].description);
+
+ }
+ }
+ DEBUG(0,(": %s\n", desc_asc));
+
+ init_uni_hdr(&r_u->hdr_desc, strlen(desc_asc));
+ init_unistr2(&r_u->desc, desc_asc, strlen(desc_asc) );
+
+ r_u->ptr_info=0xdeadbeef;
+ r_u->lang_id=q_u->lang_id;
+
+ return NT_STATUS_NO_PROBLEMO;
+}
+
+/***************************************************************************
+_lsa_enum_accounts.
+ ***************************************************************************/
+
+uint32 _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENUM_ACCOUNTS *r_u)
+{
+ GROUP_MAP *map=NULL;
+ int num_entries=0;
+ LSA_SID_ENUM *sids=&r_u->sids;
+ int i=0,j=0;
+
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
+ return NT_STATUS_INVALID_HANDLE;
+
+ /* get the list of mapped groups (domain, local, builtin) */
+ if(!enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED))
+ return NT_STATUS_NOPROBLEMO;
+
+ sids->ptr_sid = (uint32 *)talloc_zero(p->mem_ctx, (num_entries-q_u->enum_context)*sizeof(uint32));
+ sids->sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, (num_entries-q_u->enum_context)*sizeof(DOM_SID2));
+
+ if (sids->ptr_sid==NULL || sids->sid==NULL) {
+ safe_free(map);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=q_u->enum_context, j=0; i<num_entries; i++) {
+ init_dom_sid2( &(*sids).sid[j], &map[i].sid);
+ (*sids).ptr_sid[j]=1;
+ j++;
+ }
+
+ safe_free(map);
+
+ init_lsa_r_enum_accounts(r_u, j);
+
+ return NT_STATUS_NO_PROBLEMO;
+}
+
+
uint32 _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u)
{
fstring username, domname;
@@ -540,3 +667,91 @@ uint32 _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R
return r_u->status;
}
+
+/***************************************************************************
+
+ ***************************************************************************/
+
+uint32 _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENACCOUNT *r_u)
+{
+ struct lsa_info *info;
+
+ r_u->status = NT_STATUS_NOPROBLEMO;
+
+ /* find the connection policy handle. */
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
+ return NT_STATUS_INVALID_HANDLE;
+
+ /* associate the user/group SID with the (unique) handle. */
+ if ((info = (struct lsa_info *)malloc(sizeof(struct lsa_info))) == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ ZERO_STRUCTP(info);
+ info->sid = q_u->sid.sid;
+ info->access = q_u->access;
+
+ /* get a (unique) handle. open a policy on it. */
+ if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+
+ return r_u->status;
+}
+
+/***************************************************************************
+
+ ***************************************************************************/
+
+uint32 _lsa_enum_privsaccount(pipes_struct *p, LSA_Q_ENUMPRIVSACCOUNT *q_u, LSA_R_ENUMPRIVSACCOUNT *r_u)
+{
+ struct lsa_info *info=NULL;
+ GROUP_MAP map;
+ int num_entries=0;
+ uint32 count=0;
+ int i=0;
+
+ LUID_ATTR *set=NULL;
+
+ r_u->status = NT_STATUS_NOPROBLEMO;
+
+ /* find the connection policy handle. */
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
+ return NT_STATUS_INVALID_HANDLE;
+
+ if (!get_group_map_from_sid(info->sid, &map))
+ return NT_STATUS_NO_SUCH_GROUP;
+
+ for (i=1; privs[i].se_priv!=SE_PRIV_ALL; i++) {
+ if ( (map.privilege & privs[i].se_priv) == privs[i].se_priv) {
+
+ set=(LUID_ATTR *)talloc_realloc(p->mem_ctx, set, (count+1)*sizeof(LUID_ATTR));
+
+ set[count].luid.low=privs[i].se_priv;
+ set[count].luid.high=1;
+ set[count].attr=0;
+
+ count++;
+
+ }
+ }
+
+ init_lsa_r_enum_privsaccount(r_u, set, count, 0);
+
+ return r_u->status;
+}
+
+/***************************************************************************
+
+ ***************************************************************************/
+
+uint32 _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u)
+{
+ r_u->status = NT_STATUS_NOPROBLEMO;
+
+ /* find the connection policy handle. */
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
+ return NT_STATUS_INVALID_HANDLE;
+
+ r_u->access=3;
+
+ return r_u->status;
+}