From 2527f5ef52400294c98b4f4345a4f18b981ff22f Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Fri, 23 Nov 2001 15:11:22 +0000 Subject: Changed how the privileges are stored in the group mapping code. It's now an array of uint32. That's not perfect but that's better. Added more privileges too. Changed the local_lookup_rid/name functions in passdb.c to check if the group is mapped. Makes the LSA rpc calls return correct groups Corrected the return code in the LSA server code enum_sids. Only enumerate well known aliases if they are mapped to real unix groups. Won't confuse user seeing groups not available. Added a short/long view to smbgroupedit. now decoding rpc calls to add/remove privileges to sid. J.F. (This used to be commit f29774e58973f421bfa163c45bfae201a140f28c) --- source3/groupdb/mapping.c | 215 +++++++++++++++++++++++++++++---------- source3/include/mapping.h | 26 ++--- source3/libsmb/cli_lsarpc.c | 2 + source3/passdb/passdb.c | 39 +++++-- source3/rpc_parse/parse_lsa.c | 9 ++ source3/rpc_server/srv_lsa_nt.c | 12 ++- source3/rpc_server/srv_samr_nt.c | 2 +- source3/utils/smbgroupedit.c | 56 ++++++---- 8 files changed, 266 insertions(+), 95 deletions(-) (limited to 'source3') diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index 5173132af8..678824d812 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -30,11 +30,13 @@ static TDB_CONTEXT *tdb; /* used for driver files */ #define GROUP_PREFIX "UNIXGROUP/" PRIVS privs[] = { - {SE_PRIV_NONE, "no_privs", "No privilege"}, - {SE_PRIV_ADD_USERS, "add_users", "add users"}, - {SE_PRIV_ADD_MACHINES, "add_computers", "add computers to domain"}, - {SE_PRIV_PRINT_OPERATOR, "print_op", "printer operator"}, - {SE_PRIV_ALL, "all_privs", "all privileges"} + {SE_PRIV_NONE, "no_privs", "No privilege" }, /* this one MUST be first */ + {SE_PRIV_ADD_MACHINES, "SeMachineAccountPrivilege", "Add workstations to the domain" }, + {SE_PRIV_SEC_PRIV, "SeSecurityPrivilege", "Manage the audit logs" }, + {SE_PRIV_TAKE_OWNER, "SeTakeOwnershipPrivilege", "Take ownership of file" }, + {SE_PRIV_ADD_USERS, "SaAddUsers", "Add users to the domain - Samba" }, + {SE_PRIV_PRINT_OPERATOR, "SaPrintOp", "Add or remove printers - Samba" }, + {SE_PRIV_ALL, "SaAllPrivs", "all privileges" } }; /* PRIVS privs[] = { @@ -61,6 +63,9 @@ PRIVS privs[] = { { 22, "SeSystemEnvironmentPrivilege" }, { 23, "SeChangeNotifyPrivilege" }, { 24, "SeRemoteShutdownPrivilege" }, + { 25, "SeUndockPrivilege" }, + { 26, "SeSyncAgentPrivilege" }, + { 27, "SeEnableDelegationPrivilege" }, }; */ @@ -157,11 +162,15 @@ BOOL add_mapping_entry(GROUP_MAP *map, int flag) pstring key, buf; fstring string_sid=""; int len; + int i; sid_to_string(string_sid, &map->sid); - len = tdb_pack(buf, sizeof(buf), "ddffd", - map->gid, map->sid_name_use, map->nt_name, map->comment, map->privilege); + len = tdb_pack(buf, sizeof(buf), "ddff", + map->gid, map->sid_name_use, map->nt_name, map->comment); + + for (i=0; iprivileges[i]); if (len > sizeof(buf)) return False; @@ -180,22 +189,97 @@ BOOL add_mapping_entry(GROUP_MAP *map, int flag) initialise first time the mapping list ****************************************************************************/ BOOL add_initial_entry(gid_t gid, fstring sid, enum SID_NAME_USE sid_name_use, - fstring nt_name, fstring comment, uint32 privilege) + fstring nt_name, fstring comment, uint32 *privilege) { GROUP_MAP map; + int i; map.gid=gid; string_to_sid(&map.sid, sid); map.sid_name_use=sid_name_use; fstrcpy(map.nt_name, nt_name); fstrcpy(map.comment, comment); - map.privilege=privilege; + for (i=0; igid, &map->sid_name_use, &map->nt_name, &map->comment, &map->privilege); + ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff", + &map->gid, &map->sid_name_use, &map->nt_name, &map->comment); + + for (i=0; iprivileges[i]); SAFE_FREE(dbuf.dptr); if (ret != dbuf.dsize) { - DEBUG(0,("get_group_map_from_sid: mapping TDB corrupted ?\n")); + DEBUG(0,("get_group_map_from_sid: group mapping TDB corrupted ?\n")); return False; } @@ -288,6 +388,7 @@ BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map) TDB_DATA kbuf, dbuf, newkey; fstring string_sid; int ret; + int i; /* we need to enumerate the TDB to find the GID */ @@ -304,8 +405,11 @@ BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map) string_to_sid(&map->sid, string_sid); - ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddffd", - &map->gid, &map->sid_name_use, &map->nt_name, &map->comment, &map->privilege); + ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff", + &map->gid, &map->sid_name_use, &map->nt_name, &map->comment); + + for (i=0; iprivileges[i]); SAFE_FREE(dbuf.dptr); if (ret != dbuf.dsize) continue; @@ -325,8 +429,9 @@ BOOL get_group_map_from_ntname(char *name, GROUP_MAP *map) TDB_DATA kbuf, dbuf, newkey; fstring string_sid; int ret; + int i; - /* we need to enumerate the TDB to find the GID */ + /* we need to enumerate the TDB to find the SID */ for (kbuf = tdb_firstkey(tdb); kbuf.dptr; @@ -341,8 +446,11 @@ BOOL get_group_map_from_ntname(char *name, GROUP_MAP *map) string_to_sid(&map->sid, string_sid); - ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddffd", - &map->gid, &map->sid_name_use, &map->nt_name, &map->comment, &map->privilege); + ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff", + &map->gid, &map->sid_name_use, &map->nt_name, &map->comment); + + for (i=0; iprivileges[i]); SAFE_FREE(dbuf.dptr); if (ret != dbuf.dsize) continue; @@ -397,6 +505,7 @@ BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap, GROUP_MAP *mapt; int ret; int entries=0; + int i; *num_entries=0; *rmap=NULL; @@ -414,8 +523,11 @@ BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap, fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX)); - ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddffd", - &map.gid, &map.sid_name_use, &map.nt_name, &map.comment, &map.privilege); + ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff", + &map.gid, &map.sid_name_use, &map.nt_name, &map.comment); + + for (i=0; int_name, grp->gr_name); fstrcpy(map->comment, "Local Unix Group"); - map->privilege=SE_PRIV_NONE; + init_privilege(map->privileges); sid_copy(&map->sid, &sid); } @@ -632,7 +743,7 @@ BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map) if (!get_group_map_from_gid(gid, map)) { map->gid=gid; map->sid_name_use=SID_NAME_ALIAS; - map->privilege=SE_PRIV_NONE; + init_privilege(map->privileges); sid_copy(&map->sid, &global_sam_sid); sid_append_rid(&map->sid, pdb_gid_to_group_rid(gid)); diff --git a/source3/include/mapping.h b/source3/include/mapping.h index f016e148ba..9a64eefa56 100644 --- a/source3/include/mapping.h +++ b/source3/include/mapping.h @@ -20,13 +20,26 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define PRIV_ALL_INDEX 5 + +#define SE_PRIV_NONE 0x0000 +#define SE_PRIV_ADD_MACHINES 0x0006 +#define SE_PRIV_SEC_PRIV 0x0008 +#define SE_PRIV_TAKE_OWNER 0x0009 +#define SE_PRIV_ADD_USERS 0xff01 +#define SE_PRIV_PRINT_OPERATOR 0xff03 +#define SE_PRIV_ALL 0xffff + +#define ENUM_ONLY_MAPPED True +#define ENUM_ALL_MAPPED False + typedef struct _GROUP_MAP { gid_t gid; DOM_SID sid; enum SID_NAME_USE sid_name_use; fstring nt_name; fstring comment; - uint32 privilege; + uint32 privileges[PRIV_ALL_INDEX]; } GROUP_MAP; typedef struct _PRIVS { @@ -35,14 +48,3 @@ typedef struct _PRIVS { char *description; } PRIVS; -#define SE_PRIV_NONE 0x0000 -#define SE_PRIV_ADD_USERS 0x0001 -#define SE_PRIV_ADD_MACHINES 0x0002 -#define SE_PRIV_PRINT_OPERATOR 0x0004 -#define SE_PRIV_ALL 0xffff - -#define PRIV_ALL_INDEX 3 - - -#define ENUM_ONLY_MAPPED True -#define ENUM_ALL_MAPPED False diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 97f604fcb5..e944734292 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -787,6 +787,8 @@ NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, goto done; } + if (r.sids.num_entries==0) + goto done; /* Return output parameters */ diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 823feadea7..dc8e5471e1 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -75,7 +75,6 @@ static BOOL pdb_fill_default_sam(SAM_ACCOUNT *user) user->logoff_time = user->kickoff_time = user->pass_must_change_time = get_time_t_max(); - user->unknown_3 = 0x00ffffff; /* don't know */ user->logon_divs = 168; /* hours per week */ user->hours_len = 21; /* 21 times 8 bits = 168 */ @@ -536,6 +535,11 @@ BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use) } else { gid_t gid; struct group *gr; + GROUP_MAP map; + DOM_SID local_sid; + + sid_copy(&local_sid, &global_sam_sid); + sid_append_rid(&local_sid, rid); /* * Don't try to convert the rid to a name if running @@ -544,6 +548,16 @@ BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use) if (lp_hide_local_users()) return False; + + /* check if it's a mapped group */ + if (get_group_map_from_sid(local_sid, &map)) { + if (map.gid!=-1) { + DEBUG(5,("local_local_rid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid)); + fstrcpy(name, map.nt_name); + *psid_name_use = map.sid_name_use; + return True; + } + } gid = pdb_user_rid_to_gid(rid); gr = getgrgid(gid); @@ -617,13 +631,24 @@ BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid, /* * Maybe it was a group ? */ - struct group *grp = getgrnam(user); - - if(!grp) - return False; + struct group *grp; + GROUP_MAP map; + + /* check if it's a mapped group */ + if (get_group_map_from_ntname(user, &map)) { + if (map.gid!=-1) { + /* yes it's a mapped group to a valid unix group */ + sid_copy(&local_sid, &map.sid); + *psid_name_use = map.sid_name_use; + } + } else { + grp = getgrnam(user); + if(!grp) + return False; - sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid)); - *psid_name_use = SID_NAME_ALIAS; + sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid)); + *psid_name_use = SID_NAME_ALIAS; + } } sid_copy( psid, &local_sid); diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c index 6d5332794f..10a9efbe49 100644 --- a/source3/rpc_parse/parse_lsa.c +++ b/source3/rpc_parse/parse_lsa.c @@ -854,6 +854,15 @@ static BOOL lsa_io_sid_enum(char *desc, LSA_SID_ENUM *sen, prs_struct *ps, return False; if(!prs_uint32("ptr_sid_enum", ps, depth, &sen->ptr_sid_enum)) return False; + + /* + if the ptr is NULL, leave here. checked from a real w2k trace. + JFM, 11/23/2001 + */ + + if (sen->ptr_sid_enum==0) + return True; + if(!prs_uint32("num_entries2", ps, depth, &sen->num_entries2)) return False; diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index f221582d86..03d48aa5e7 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -543,7 +543,7 @@ NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIV return NT_STATUS_INVALID_HANDLE; if (enum_context >= PRIV_ALL_INDEX) - return NT_STATUS_UNABLE_TO_FREE_VM; + return NT_STATUS_NO_MORE_ENTRIES; entries = (LSA_PRIV_ENTRY *)talloc_zero(p->mem_ctx, sizeof(LSA_PRIV_ENTRY) * (PRIV_ALL_INDEX)); if (entries==NULL) @@ -625,6 +625,9 @@ NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENU if(!enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED)) return NT_STATUS_OK; + if (q_u->enum_context >= num_entries) + return NT_STATUS_NO_MORE_ENTRIES; + 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)); @@ -707,7 +710,7 @@ NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENAC } /*************************************************************************** - + For a given SID, enumerate all the privilege this account has. ***************************************************************************/ NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, LSA_Q_ENUMPRIVSACCOUNT *q_u, LSA_R_ENUMPRIVSACCOUNT *r_u) @@ -729,7 +732,7 @@ NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, LSA_Q_ENUMPRIVSACCOUNT *q_u, LS 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) { + if ( check_priv_in_privilege(map.privileges, privs[i].se_priv)) { set=(LUID_ATTR *)talloc_realloc(p->mem_ctx, set, (count+1)*sizeof(LUID_ATTR)); if (set == NULL) return NT_STATUS_NO_MEMORY; @@ -738,8 +741,7 @@ NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, LSA_Q_ENUMPRIVSACCOUNT *q_u, LS set[count].luid.high=1; set[count].attr=0; - count++; - + count++; } } diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index c872c9f99f..f1f3040ba4 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -810,7 +810,7 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM /* well-known aliases */ if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) { - enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ALL_MAPPED); + enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED); if (num_entries != 0) { *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP)); diff --git a/source3/utils/smbgroupedit.c b/source3/utils/smbgroupedit.c index 8d99e8e600..b6138fa576 100644 --- a/source3/utils/smbgroupedit.c +++ b/source3/utils/smbgroupedit.c @@ -38,7 +38,7 @@ extern int optind; static void usage(void) { if (getuid() == 0) { - printf("groupedit options\n"); + printf("smbgroupedit options\n"); } else { printf("You need to be root to use this tool!\n"); } @@ -47,6 +47,8 @@ static void usage(void) printf(" -n group NT group name\n"); printf(" -p privilege only local\n"); printf(" -v list groups\n"); + printf(" -l long list (include details)\n"); + printf(" -s short list (default)\n"); printf(" -c SID change group\n"); printf(" -u unix group\n"); printf(" -x group delete this group\n"); @@ -60,16 +62,12 @@ static void usage(void) **********************************************************/ int addgroup(char *group, enum SID_NAME_USE sid_type, char *ntgroup, char *ntcomment, char *privilege) { - uint32 se_priv; + uint32 se_priv[PRIV_ALL_INDEX]; gid_t gid; DOM_SID sid; fstring string_sid; fstring name, comment; -/* convert_priv_from_text(&se_priv, privilege);*/ - - se_priv=0x0; - gid=nametogid(group); if (gid==-1) return -1; @@ -87,6 +85,10 @@ int addgroup(char *group, enum SID_NAME_USE sid_type, char *ntgroup, char *ntcom else fstrcpy(comment, ntcomment); + init_privilege(se_priv); + if (privilege!=NULL) + convert_priv_from_text(se_priv, privilege); + if(!add_initial_entry(gid, string_sid, sid_type, name, comment, se_priv)) return -1; @@ -101,7 +103,7 @@ int changegroup(char *sid_string, char *group, enum SID_NAME_USE sid_type, char DOM_SID sid; GROUP_MAP map; gid_t gid; - uint32 se_priv; + uint32 se_priv[PRIV_ALL_INDEX]; string_to_sid(&sid, sid_string); @@ -139,8 +141,10 @@ int changegroup(char *sid_string, char *group, enum SID_NAME_USE sid_type, char /* Change the privilege if new one */ if (privilege!=NULL) { - convert_priv_from_text(&se_priv, privilege); - map.privilege=se_priv; + int i; + convert_priv_from_text(se_priv, privilege); + for(i=0; i Unix group\n"); if (!enum_group_mapping(sid_type, &map, &entries, ENUM_ALL_MAPPED)) return -1; @@ -185,10 +190,18 @@ int listgroup(enum SID_NAME_USE sid_type) for (i=0; i %s\n", map[i].nt_name, string_sid, gidtoname(map[i].gid)); + else { + printf("%s\n", map[i].nt_name); + printf("\tSID : %s\n", string_sid); + printf("\tUnix group: %s\n", gidtoname(map[i].gid)); + printf("\tGroup type: %s\n", group_type); + printf("\tComment : %s\n", map[i].comment); + printf("\tPrivilege : %s\n\n", priv_text); + } } return 0; @@ -207,7 +220,8 @@ int main (int argc, char **argv) BOOL nt_group = False; BOOL priv = False; BOOL group_type = False; - + BOOL long_list = False; + char *group = NULL; char *sid = NULL; char *ntgroup = NULL; @@ -235,7 +249,7 @@ int main (int argc, char **argv) exit(1); } - while ((ch = getopt(argc, argv, "a:c:d:n:p:t:u:vx:")) != EOF) { + while ((ch = getopt(argc, argv, "a:c:d:ln:p:st:u:vx:")) != EOF) { switch(ch) { case 'a': add_group = True; @@ -248,6 +262,9 @@ int main (int argc, char **argv) case 'd': group_desc=optarg; break; + case 'l': + long_list = True; + break; case 'n': nt_group = True; ntgroup=optarg; @@ -256,6 +273,9 @@ int main (int argc, char **argv) priv = True; privilege=optarg; break; + case 's': + long_list = False; + break; case 't': group_type = True; groupt=optarg; @@ -325,7 +345,7 @@ int main (int argc, char **argv) return addgroup(group, sid_type, ntgroup, group_desc, privilege); if (view_group) - return listgroup(sid_type); + return listgroup(sid_type, long_list); if (delete_group) return deletegroup(group); -- cgit