summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2002-01-02 07:27:33 +0000
committerJeremy Allison <jra@samba.org>2002-01-02 07:27:33 +0000
commit71f982c9f2f450d660406d6015ff9756bf317218 (patch)
tree2413460c23456053e84fd88156bf32b3140333f2
parent493c34b8f3de4b402d9496424e250faa4743e310 (diff)
downloadsamba-71f982c9f2f450d660406d6015ff9756bf317218.tar.gz
samba-71f982c9f2f450d660406d6015ff9756bf317218.tar.bz2
samba-71f982c9f2f450d660406d6015ff9756bf317218.zip
Make user enumeration work for w2k and win9x.
This means different return sizes depending on client bugs. This sucks :-(. Jeremy. (This used to be commit f6592628eb526c487069bb3fcd809aca930e668e)
-rw-r--r--source3/include/rpc_samr.h5
-rw-r--r--source3/rpc_server/srv_samr_nt.c156
2 files changed, 89 insertions, 72 deletions
diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h
index 36c9f69821..59325ca88d 100644
--- a/source3/include/rpc_samr.h
+++ b/source3/include/rpc_samr.h
@@ -646,7 +646,10 @@ typedef struct r_samr_open_domain_info
} SAMR_R_OPEN_DOMAIN;
-#define MAX_SAM_ENTRIES 0x400
+#define MAX_SAM_ENTRIES_W2K 0x400
+#define MAX_SAM_ENTRIES_W95 50
+/* The following should be the greater of the preceeding two. */
+#define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
typedef struct samr_entry_info
{
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index 17d5f2eb6a..febbf21f67 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -6,7 +6,7 @@
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997.
* Copyright (C) Marc Jacobsen 1999.
- * Copyright (C) Jeremy Allison 2001.
+ * Copyright (C) Jeremy Allison 2001-2002.
* Copyright (C) Jean François Micouleau 1998-2001.
*
* This program is free software; you can redistribute it and/or modify
@@ -42,10 +42,10 @@ extern rid_name builtin_alias_rids[];
typedef struct _disp_info {
BOOL user_dbloaded;
- BOOL group_dbloaded;
- uint32 num_account;
- uint32 total_size;
+ uint32 num_user_account;
DISP_USER_INFO *disp_user_info;
+ BOOL group_dbloaded;
+ uint32 num_group_account;
DISP_GROUP_INFO *disp_group_info;
} DISP_INFO;
@@ -57,6 +57,28 @@ struct samr_info {
};
/*******************************************************************
+ Create a samr_info struct.
+********************************************************************/
+
+static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
+{
+ struct samr_info *info;
+ fstring sid_str;
+
+ if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
+ return NULL;
+
+ ZERO_STRUCTP(info);
+ if (psid) {
+ DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_to_string(sid_str, psid) ));
+ sid_copy( &info->sid, psid);
+ } else {
+ DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
+ }
+ return info;
+}
+
+/*******************************************************************
Function to free the per handle data.
********************************************************************/
static void free_samr_db(struct samr_info *info)
@@ -64,14 +86,14 @@ static void free_samr_db(struct samr_info *info)
int i;
if (info->disp_info.group_dbloaded) {
- for (i=0; i<info->disp_info.num_account; i++)
+ for (i=0; i<info->disp_info.num_group_account; i++)
SAFE_FREE(info->disp_info.disp_group_info[i].grp);
SAFE_FREE(info->disp_info.disp_group_info);
}
if (info->disp_info.user_dbloaded){
- for (i=0; i<info->disp_info.num_account; i++)
+ for (i=0; i<info->disp_info.num_user_account; i++)
pdb_free_sam(&info->disp_info.disp_user_info[i].sam);
SAFE_FREE(info->disp_info.disp_user_info);
@@ -79,8 +101,8 @@ static void free_samr_db(struct samr_info *info)
info->disp_info.user_dbloaded=False;
info->disp_info.group_dbloaded=False;
- info->disp_info.num_account=0;
- info->disp_info.total_size=0;
+ info->disp_info.num_group_account=0;
+ info->disp_info.num_user_account=0;
}
@@ -89,7 +111,7 @@ static void free_samr_info(void *ptr)
struct samr_info *info=(struct samr_info *) ptr;
free_samr_db(info);
- SAFE_FREE(ptr);
+ SAFE_FREE(info);
}
/*******************************************************************
@@ -114,8 +136,10 @@ static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
if (!sam_pass)
return;
- if (sam_pass->lm_pw) memset(sam_pass->lm_pw, '\0', 16);
- if (sam_pass->nt_pw) memset(sam_pass->nt_pw, '\0', 16);
+ if (sam_pass->lm_pw)
+ memset(sam_pass->lm_pw, '\0', 16);
+ if (sam_pass->nt_pw)
+ memset(sam_pass->nt_pw, '\0', 16);
}
@@ -146,11 +170,11 @@ static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask)
}
/* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
- if (info->disp_info.num_account % MAX_SAM_ENTRIES == 0) {
+ if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
pwd_array=(DISP_USER_INFO *)Realloc(info->disp_info.disp_user_info,
- (info->disp_info.num_account+MAX_SAM_ENTRIES)*sizeof(DISP_USER_INFO));
+ (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(DISP_USER_INFO));
if (pwd_array==NULL)
return NT_STATUS_NO_MEMORY;
@@ -159,11 +183,11 @@ static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask)
}
/* link the SAM_ACCOUNT to the array */
- info->disp_info.disp_user_info[info->disp_info.num_account].sam=pwd;
+ info->disp_info.disp_user_info[info->disp_info.num_user_account].sam=pwd;
- DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_account));
+ DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
- info->disp_info.num_account++;
+ info->disp_info.num_user_account++;
}
pdb_endsampwent();
@@ -194,9 +218,9 @@ static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
- info->disp_info.num_account=group_entries;
+ info->disp_info.num_group_account=group_entries;
- grp_array=(DISP_GROUP_INFO *)malloc(info->disp_info.num_account*sizeof(DISP_GROUP_INFO));
+ grp_array=(DISP_GROUP_INFO *)malloc(info->disp_info.num_group_account*sizeof(DISP_GROUP_INFO));
if (group_entries!=0 && grp_array==NULL) {
SAFE_FREE(map);
@@ -337,12 +361,9 @@ NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN
return NT_STATUS_INVALID_HANDLE;
/* associate the domain SID with the (unique) handle. */
- if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
+ if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
return NT_STATUS_NO_MEMORY;
- ZERO_STRUCTP(info);
- info->sid = q_u->dom_sid.sid;
-
/* get a (unique) handle. open a policy on it. */
if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -847,8 +868,12 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_
SAM_DISPINFO_CTR *ctr;
uint32 temp_size=0, total_data_size=0;
- uint32 i;
NTSTATUS disp_ret;
+ uint32 num_account = 0;
+ enum remote_arch_types ra_type = get_remote_arch();
+ int max_sam_entries;
+
+ max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
r_u->status = NT_STATUS_OK;
@@ -904,12 +929,14 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_
DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
return r_u->status;
}
+ num_account = info->disp_info.num_user_account;
break;
case 0x3:
case 0x5:
r_u->status = load_group_domain_entries(info, &info->sid);
if (NT_STATUS_IS_ERR(r_u->status))
return r_u->status;
+ num_account = info->disp_info.num_group_account;
break;
default:
DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
@@ -917,19 +944,19 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_
}
/* first limit the number of entries we will return */
- if(max_entries > MAX_SAM_ENTRIES) {
- DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, MAX_SAM_ENTRIES));
- max_entries = MAX_SAM_ENTRIES;
+ if(max_entries > max_sam_entries) {
+ DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
+ max_entries = max_sam_entries;
}
- if (enum_context > info->disp_info.num_account) {
+ if (enum_context > num_account) {
DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
return NT_STATUS_OK;
}
/* verify we won't overflow */
- if (max_entries > info->disp_info.num_account-enum_context) {
- max_entries = info->disp_info.num_account-enum_context;
+ if (max_entries > num_account-enum_context) {
+ max_entries = num_account-enum_context;
DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
}
@@ -1000,9 +1027,9 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_
}
/* calculate the total size */
- total_data_size=info->disp_info.num_account*struct_size;
+ total_data_size=num_account*struct_size;
- if (enum_context+max_entries < info->disp_info.num_account)
+ if (enum_context+max_entries < num_account)
r_u->status = STATUS_MORE_ENTRIES;
DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
@@ -1013,7 +1040,6 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_
}
-
/*******************************************************************
samr_reply_query_aliasinfo
********************************************************************/
@@ -1380,12 +1406,9 @@ NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN
return NT_STATUS_NO_SUCH_USER;
/* associate the user's SID with the new handle. */
- if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
+ if ((info = get_samr_info_by_sid(&sid)) == NULL)
return NT_STATUS_NO_MEMORY;
- ZERO_STRUCTP(info);
- info->sid = sid;
-
/* get a (unique) handle. open a policy on it. */
if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -1778,7 +1801,7 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
return r_u->status;
}
- num_users=info->disp_info.num_account;
+ num_users=info->disp_info.num_user_account;
free_samr_db(info);
r_u->status=load_group_domain_entries(info, &global_sam_sid);
@@ -1786,7 +1809,7 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
return r_u->status;
}
- num_groups=info->disp_info.num_account;
+ num_groups=info->disp_info.num_group_account;
free_samr_db(info);
/* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
@@ -1961,7 +1984,7 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_
}
/* associate the user's SID with the new handle. */
- if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL) {
+ if ((info = get_samr_info_by_sid(&sid)) == NULL) {
pdb_free_sam(&sam_pass);
return NT_STATUS_NO_MEMORY;
}
@@ -1996,10 +2019,9 @@ NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CO
r_u->status = NT_STATUS_OK;
/* associate the user's SID with the new handle. */
- if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
+ if ((info = get_samr_info_by_sid(NULL)) == NULL)
return NT_STATUS_NO_MEMORY;
- ZERO_STRUCTP(info);
info->status = q_u->unknown_0;
/* get a (unique) handle. open a policy on it. */
@@ -2022,10 +2044,9 @@ NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u
r_u->status = NT_STATUS_OK;
/* associate the user's SID with the new handle. */
- if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
+ if ((info = get_samr_info_by_sid(NULL)) == NULL)
return NT_STATUS_NO_MEMORY;
- ZERO_STRUCTP(info);
info->status = q_u->access_mask;
/* get a (unique) handle. open a policy on it. */
@@ -2147,12 +2168,9 @@ NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OP
*/
/* associate the user's SID with the new handle. */
- if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
+ if ((info = get_samr_info_by_sid(&sid)) == NULL)
return NT_STATUS_NO_MEMORY;
- ZERO_STRUCTP(info);
- info->sid = sid;
-
/* get a (unique) handle. open a policy on it. */
if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -3229,18 +3247,16 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S
r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
/* add the group to the mapping table */
+ sid_copy(&info_sid, &global_sam_sid);
+ sid_append_rid(&info_sid, r_u->rid);
+ sid_to_string(sid_string, &info_sid);
+
if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
return NT_STATUS_ACCESS_DENIED;
- if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
+ if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
return NT_STATUS_NO_MEMORY;
- ZERO_STRUCTP(info);
-
- sid_copy(&info_sid, &global_sam_sid);
- sid_append_rid(&info->sid, r_u->rid);
- sid_to_string(sid_string, &info->sid);
-
/* get a (unique) handle. open a policy on it. */
if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -3255,6 +3271,7 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S
NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
{
DOM_SID dom_sid;
+ DOM_SID info_sid;
fstring name;
fstring sid_string;
struct group *grp;
@@ -3287,19 +3304,17 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S
r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
- if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- ZERO_STRUCTP(info);
-
- sid_copy(&info->sid, &global_sam_sid);
- sid_append_rid(&info->sid, r_u->rid);
- sid_to_string(sid_string, &info->sid);
+ sid_copy(&info_sid, &global_sam_sid);
+ sid_append_rid(&info_sid, r_u->rid);
+ sid_to_string(sid_string, &info_sid);
/* add the group to the mapping table */
if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
return NT_STATUS_ACCESS_DENIED;
+ if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
+ return NT_STATUS_NO_MEMORY;
+
/* get a (unique) handle. open a policy on it. */
if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -3455,6 +3470,7 @@ NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_
NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
{
DOM_SID sid;
+ DOM_SID info_sid;
GROUP_MAP map;
struct samr_info *info;
fstring sid_string;
@@ -3466,14 +3482,12 @@ NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_G
if (!sid_equal(&sid, &global_sam_sid))
return NT_STATUS_ACCESS_DENIED;
- if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- ZERO_STRUCTP(info);
+ sid_copy(&info_sid, &global_sam_sid);
+ sid_append_rid(&info_sid, q_u->rid_group);
+ sid_to_string(sid_string, &info_sid);
- sid_copy(&info->sid, &global_sam_sid);
- sid_append_rid(&info->sid, q_u->rid_group);
- sid_to_string(sid_string, &info->sid);
+ if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
+ return NT_STATUS_NO_MEMORY;
DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
@@ -3554,7 +3568,7 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW
DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
return r_u->status;
}
- num_users=info->disp_info.num_account;
+ num_users=info->disp_info.num_user_account;
free_samr_db(info);
r_u->status=load_group_domain_entries(info, &global_sam_sid);
@@ -3562,7 +3576,7 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW
DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
return r_u->status;
}
- num_groups=info->disp_info.num_account;
+ num_groups=info->disp_info.num_group_account;
free_samr_db(info);
/* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */