From c6ad04b8fb4ee5cbf862a35b4c143a6f75555718 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 30 Nov 1998 22:42:13 +0000 Subject: attempting to fix "domain user map" up, but it's a bit complicated. i may simply go for a response in the NetSamLogon returning the unix username, forcing the NT user to appear to be a unix user, however even that is fraught with implications. might just have to go the whole hog and do this tuple thing, "unix_name + nt_name" always associated together... issue with api_net_sam_logon, getsam21pwent() being called twice, the second time overwriting static buffer data (argh) so had to make a copy. noticed a nested "become_root()"/"unbecome_root()" which will have to be tracked down... (This used to be commit 474f94f419a531e33b475249da7efb99ac22f454) --- source3/lib/domain_namemap.c | 88 +++++++++++++++++++++++----------------- source3/lib/sids.c | 11 ++++- source3/lib/util_pwdb.c | 1 - source3/passdb/sampassdb.c | 17 ++++++-- source3/rpc_server/srv_netlog.c | 81 ++++++++++++++++++++++++++++--------- source3/smbd/reply.c | 90 +++++++++++++++++++++++++---------------- 6 files changed, 192 insertions(+), 96 deletions(-) (limited to 'source3') diff --git a/source3/lib/domain_namemap.c b/source3/lib/domain_namemap.c index cc96a014c4..09908be5fe 100644 --- a/source3/lib/domain_namemap.c +++ b/source3/lib/domain_namemap.c @@ -273,6 +273,9 @@ static void delete_map_list(ubi_slList *map_list) ***************************************************************************/ static BOOL make_mydomain_sid(DOM_NAME_MAP *grp, DOM_MAP_TYPE type) { + int ret = False; + fstring sid_str; + if (!map_domain_name_to_sid(&grp->sid, &(grp->nt_domain))) { DEBUG(0,("make_mydomain_sid: unknown domain %s\n", @@ -294,7 +297,7 @@ static BOOL make_mydomain_sid(DOM_NAME_MAP *grp, DOM_MAP_TYPE type) grp->unix_name, grp->nt_name)); return False; } - return True; + ret = True; } else if (lookup_wk_user_name(grp->nt_name, grp->nt_domain, &grp->sid, &grp->type) == 0x0) { @@ -304,7 +307,7 @@ static BOOL make_mydomain_sid(DOM_NAME_MAP *grp, DOM_MAP_TYPE type) grp->nt_domain, grp->nt_name)); return False; } - return True; + ret = True; } else if (lookup_wk_group_name(grp->nt_name, grp->nt_domain, &grp->sid, &grp->type) == 0x0) { @@ -314,12 +317,10 @@ static BOOL make_mydomain_sid(DOM_NAME_MAP *grp, DOM_MAP_TYPE type) grp->nt_domain, grp->nt_name)); return False; } - return True; + ret = True; } else { - BOOL ret; - fstring sid_str; switch (type) { case DOM_MAP_USER: @@ -340,45 +341,57 @@ static BOOL make_mydomain_sid(DOM_NAME_MAP *grp, DOM_MAP_TYPE type) } ret = pwdb_unixid_to_sam_sid(grp->unix_id, grp->type, &grp->sid); - sid_to_string(sid_str, &grp->sid); - DEBUG(10,("nt name %s gid %d mapped to %s\n", - grp->nt_name, grp->unix_id, sid_str)); - return ret; } - return False; + sid_to_string(sid_str, &grp->sid); + DEBUG(10,("nt name %s\\%s gid %d mapped to %s\n", + grp->nt_domain, grp->nt_name, grp->unix_id, sid_str)); + return ret; } /************************************************************************** makes a group sid out of an nt domain, nt group name or a unix group name. ***************************************************************************/ -static BOOL unix_name_to_group_info(DOM_NAME_MAP *grp, DOM_MAP_TYPE type) +static BOOL unix_name_to_nt_name_info(DOM_NAME_MAP *map, DOM_MAP_TYPE type) { - struct group *gptr = NULL; - /* * Attempt to get the unix gid_t for this name. */ - DEBUG(5,("unix_name_to_group_info: unix_name:%s\n", grp->unix_name)); + DEBUG(5,("unix_name_to_nt_name_info: unix_name:%s\n", map->unix_name)); - gptr = (struct group *)getgrnam(grp->unix_name); - if (gptr == NULL) + if (type == DOM_MAP_USER) { - DEBUG(0,("unix_name_to_group_info: getgrnam for group %s\ -failed. Error was %s.\n", grp->unix_name, strerror(errno) )); - return False; + struct passwd *pwptr = Get_Pwnam(map->unix_name, False); + if (pwptr == NULL) + { + DEBUG(0,("unix_name_to_nt_name_info: Get_Pwnam for user %s\ +failed. Error was %s.\n", map->unix_name, strerror(errno) )); + return False; + } + + map->unix_id = (uint32)pwptr->pw_uid; } + else + { + struct group *gptr = getgrnam(map->unix_name); + if (gptr == NULL) + { + DEBUG(0,("unix_name_to_nt_name_info: getgrnam for group %s\ +failed. Error was %s.\n", map->unix_name, strerror(errno) )); + return False; + } - grp->unix_id = (uint32)gptr->gr_gid; + map->unix_id = (uint32)gptr->gr_gid; + } - DEBUG(5,("unix_name_to_group_info: unix gid:%d\n", grp->unix_id)); + DEBUG(5,("unix_name_to_nt_name_info: unix gid:%d\n", map->unix_id)); /* * Now map the name to an NT SID+RID. */ - if (grp->nt_domain != NULL && !strequal(grp->nt_domain, global_sam_name)) + if (map->nt_domain != NULL && !strequal(map->nt_domain, global_sam_name)) { /* Must add client-call lookup code here, to * resolve remote domain's sid and the group's rid, @@ -394,15 +407,15 @@ failed. Error was %s.\n", grp->unix_name, strerror(errno) )); * RIDs in a foriegn domain. */ - if (!map_domain_name_to_sid(&grp->sid, &(grp->nt_domain))) + if (!map_domain_name_to_sid(&map->sid, &(map->nt_domain))) { - DEBUG(0,("unix_name_to_group_info: no known sid for %s\n", - grp->nt_domain)); + DEBUG(0,("unix_name_to_nt_name_info: no known sid for %s\n", + map->nt_domain)); return False; } } - return make_mydomain_sid(grp, type); + return make_mydomain_sid(map, type); } static BOOL make_name_entry(name_map_entry **new_ep, @@ -440,7 +453,7 @@ static BOOL make_name_entry(name_map_entry **new_ep, * look up the group names, make the Group-SID and unix gid */ - if (!unix_name_to_group_info(&(*new_ep)->grp, type)) + if (!unix_name_to_nt_name_info(&(*new_ep)->grp, type)) { delete_name_entry((*new_ep)); return False; @@ -559,7 +572,7 @@ static ubi_slList *load_name_map(DOM_MAP_TYPE type) pstring unixname; pstring nt_name; fstring nt_domain; - fstring nt_group; + fstring ntname; char *p; DEBUG(10,("Read line |%s|\n", s)); @@ -589,21 +602,24 @@ static ubi_slList *load_name_map(DOM_MAP_TYPE type) if (p == NULL) { memset(nt_domain, 0, sizeof(nt_domain)); - fstrcpy(nt_group, nt_name); + fstrcpy(ntname, nt_name); } else { *p = 0; p++; fstrcpy(nt_domain, nt_name); - fstrcpy(nt_group , p); + fstrcpy(ntname , p); } - if (make_name_entry(&new_ep, nt_domain, nt_group, unixname, type)) + if (make_name_entry(&new_ep, nt_domain, ntname, unixname, type)) { ubi_slAddTail(map_list, (ubi_slNode *)new_ep); DEBUG(5,("unixname = %s, ntname = %s\\%s type = %d\n", - unixname, nt_domain, nt_group, new_ep->grp.type)); + new_ep->grp.unix_name, + new_ep->grp.nt_domain, + new_ep->grp.nt_name, + new_ep->grp.type)); } } @@ -647,7 +663,7 @@ static BOOL map_unixname(DOM_MAP_TYPE type, if (strequal(gmep->grp.unix_name, unixname)) { copy_grp_map_entry(grp_info, &gmep->grp); - DEBUG(7,("map_unixname: Mapping unix group %s to nt group %s.\n", + DEBUG(7,("map_unixname: Mapping unix name %s to nt group %s.\n", gmep->grp.unix_name, gmep->grp.nt_name )); return True; } @@ -680,7 +696,7 @@ static BOOL map_ntname(DOM_MAP_TYPE type, char *ntname, char *ntdomain, strequal(gmep->grp.nt_domain, ntdomain)) { copy_grp_map_entry(grp_info, &gmep->grp); - DEBUG(7,("map_ntname: Mapping unix group %s to nt group %s.\n", + DEBUG(7,("map_ntname: Mapping unix name %s to nt name %s.\n", gmep->grp.unix_name, gmep->grp.nt_name )); return True; } @@ -711,7 +727,7 @@ static BOOL map_sid(DOM_MAP_TYPE type, if (sid_equal(&gmep->grp.sid, psid)) { copy_grp_map_entry(grp_info, &gmep->grp); - DEBUG(7,("map_sid: Mapping unix group %s to nt group %s.\n", + DEBUG(7,("map_sid: Mapping unix name %s to nt name %s.\n", gmep->grp.unix_name, gmep->grp.nt_name )); return True; } @@ -744,7 +760,7 @@ static BOOL map_unixid(DOM_MAP_TYPE type, uint32 unix_id, DOM_NAME_MAP *grp_info if (gmep->grp.unix_id == unix_id) { copy_grp_map_entry(grp_info, &gmep->grp); - DEBUG(7,("map_unixid: Mapping unix group %s to nt group %s type %d\n", + DEBUG(7,("map_unixid: Mapping unix name %s to nt name %s type %d\n", gmep->grp.unix_name, gmep->grp.nt_name, gmep->grp.type)); return True; } diff --git a/source3/lib/sids.c b/source3/lib/sids.c index 854e9d5786..f5fed0f656 100644 --- a/source3/lib/sids.c +++ b/source3/lib/sids.c @@ -283,6 +283,13 @@ BOOL generate_sam_sid(char *domain_name) uchar raw_sid_data[12]; pstrcpy(sid_file, lp_smb_passwd_file()); + + if (sid_file[0] == 0) + { + DEBUG(0,("cannot find smb passwd file\n")); + return False; + } + p = strrchr(sid_file, '/'); if (p != NULL) { @@ -456,10 +463,10 @@ BOOL map_domain_name_to_sid(DOM_SID *sid, char **nt_domain) if ((*nt_domain)[0] == 0) { - DEBUG(5,("map_domain_name_to_sid: overriding blank name to %s\n", - global_sam_name)); free(*nt_domain); (*nt_domain) = strdup(global_sam_name); + DEBUG(5,("map_domain_name_to_sid: overriding blank name to %s\n", + (*nt_domain))); sid_copy(sid, &global_sam_sid); return True; } diff --git a/source3/lib/util_pwdb.c b/source3/lib/util_pwdb.c index 74d5ff6794..588070f7b8 100644 --- a/source3/lib/util_pwdb.c +++ b/source3/lib/util_pwdb.c @@ -141,7 +141,6 @@ uint32 lookup_wk_user_name(const char *user_name, const char *domain, if (usr_name != NULL) { - sid_copy(sid, &global_sid_S_1_5_20); sid_append_rid(sid, domain_user_rids[i].rid); return 0; } diff --git a/source3/passdb/sampassdb.c b/source3/passdb/sampassdb.c index 95055ed298..bcd2764abc 100644 --- a/source3/passdb/sampassdb.c +++ b/source3/passdb/sampassdb.c @@ -126,12 +126,15 @@ struct sam_passwd *getsam21pwent(void *vp) does not have search facilities. *************************************************************************/ -struct sam_passwd *iterate_getsam21pwntnam(const char *name) +struct sam_passwd *iterate_getsam21pwntnam(const char *ntname) { + fstring nt_name; struct sam_passwd *pwd = NULL; void *fp = NULL; - DEBUG(10, ("search by name: %s\n", name)); + DEBUG(10, ("search by name: %s\n", ntname)); + + fstrcpy(nt_name, ntname); /* Open the smb password database - not for update. */ fp = startsmbpwent(False); @@ -142,14 +145,14 @@ struct sam_passwd *iterate_getsam21pwntnam(const char *name) return NULL; } - while ((pwd = getsam21pwent(fp)) != NULL && !strequal(pwd->nt_name, name)) + while ((pwd = getsam21pwent(fp)) != NULL && !strequal(pwd->nt_name, nt_name)) { DEBUG(10, ("iterate: %s 0x%x\n", pwd->nt_name, pwd->user_rid)); } if (pwd != NULL) { - DEBUG(10, ("found by name: %s\n", name)); + DEBUG(10, ("found by name: %s\n", nt_name)); } endsmbpwent(fp); @@ -436,6 +439,9 @@ struct sam_passwd *pwdb_sam_map_names(struct sam_passwd *sam) if (sam->unix_uid == (uid_t)-1 ) sam->unix_uid = (uid_t)gmep.unix_id; if (sam->user_rid == 0xffffffff) sid_split_rid(&gmep.sid, &sam->user_rid); + DEBUG(10,("pwdb_sam_map_name: found unix user %s nt %s uid %d rid 0x%x\n", + sam->unix_name, sam->nt_name, sam->unix_uid, sam->user_rid)); + /* * group details */ @@ -511,5 +517,8 @@ you will get this warning only once (for all trust accounts)\n", unix_name)); if (sam->unix_gid == (gid_t)-1 ) sam->unix_gid = (gid_t)gmep.unix_id; if (sam->group_rid == 0xffffffff) sid_split_rid(&gmep.sid, &sam->group_rid); + DEBUG(10,("pwdb_sam_map_name: found gid %d and group rid 0x%x for unix user %s\n", + sam->unix_gid, sam->group_rid, sam->unix_name)); + return sam; } diff --git a/source3/rpc_server/srv_netlog.c b/source3/rpc_server/srv_netlog.c index 4f49735ca0..bb8bc59bc5 100644 --- a/source3/rpc_server/srv_netlog.c +++ b/source3/rpc_server/srv_netlog.c @@ -599,8 +599,26 @@ static void api_net_sam_logon( uint16 vuid, DOM_CRED srv_cred; struct sam_passwd *sam_pass = NULL; UNISTR2 *uni_samlogon_user = NULL; + UNISTR2 *uni_domain = NULL; fstring nt_username; + NTTIME logon_time ; + NTTIME logoff_time ; + NTTIME kickoff_time ; + NTTIME pass_last_set_time ; + NTTIME pass_can_change_time ; + NTTIME pass_must_change_time; + + fstring nt_name ; + fstring full_name ; + fstring logon_script; + fstring profile_path; + fstring home_dir ; + fstring dir_drive ; + + uint32 user_rid ; + uint32 group_rid; + user_struct *vuser = NULL; if ((vuser = get_valid_user_struct(vuid)) == NULL) @@ -630,6 +648,7 @@ static void api_net_sam_logon( uint16 vuid, case INTERACTIVE_LOGON_TYPE: { uni_samlogon_user = &(q_l.sam_id.ctr->auth.id1.uni_user_name); + uni_domain = &(q_l.sam_id.ctr->auth.id1.uni_domain_name); DEBUG(3,("SAM Logon (Interactive). Domain:[%s]. ", global_sam_name)); break; @@ -637,6 +656,7 @@ static void api_net_sam_logon( uint16 vuid, case NET_LOGON_TYPE: { uni_samlogon_user = &(q_l.sam_id.ctr->auth.id2.uni_user_name); + uni_domain = &(q_l.sam_id.ctr->auth.id2.uni_domain_name); DEBUG(3,("SAM Logon (Network). Domain:[%s]. ", global_sam_name)); break; @@ -654,9 +674,12 @@ static void api_net_sam_logon( uint16 vuid, if (status == 0) { - pstrcpy(nt_username, unistrn2(uni_samlogon_user->buffer, - uni_samlogon_user->uni_str_len)); - + fstrcpy(nt_username, unistr2_to_str(uni_samlogon_user)); +#if 0 + slprintf(nt_username, sizeof(nt_username), "%s\\%s", + unistr2_to_str(uni_domain), + unistr2_to_str(uni_samlogon_user)); +#endif DEBUG(3,("User:[%s]\n", nt_username)); become_root(True); @@ -674,6 +697,26 @@ static void api_net_sam_logon( uint16 vuid, } } + if (status == 0x0) + { + logon_time = sam_pass->logon_time; + logoff_time = sam_pass->logoff_time; + kickoff_time = sam_pass->kickoff_time; + pass_last_set_time = sam_pass->pass_last_set_time; + pass_can_change_time = sam_pass->pass_can_change_time; + pass_must_change_time = sam_pass->pass_must_change_time; + + fstrcpy(nt_name , sam_pass->nt_name); + fstrcpy(full_name , sam_pass->full_name); + fstrcpy(logon_script, sam_pass->logon_script); + fstrcpy(profile_path, sam_pass->profile_path); + fstrcpy(home_dir , sam_pass->home_dir); + fstrcpy(dir_drive , sam_pass->dir_drive); + + user_rid = sam_pass->user_rid; + group_rid = sam_pass->group_rid; + } + /* validate password - if required */ if (status == 0 && !(IS_BITS_SET_ALL(sam_pass->acct_ctrl, ACB_PWNOTREQ))) @@ -705,7 +748,7 @@ static void api_net_sam_logon( uint16 vuid, if (status == 0) { int num_gids = 0; - DOMAIN_GRP *grp_mem; + DOMAIN_GRP *grp_mem = NULL; /* set up pointer indicating user/password failed to be found */ usr_info.ptr_user_info = 0; @@ -721,25 +764,25 @@ static void api_net_sam_logon( uint16 vuid, num_gids = make_dom_gids(grp_mem, num_gids, &gids); make_net_user_info3(&usr_info, - &sam_pass->logon_time, - &sam_pass->logoff_time, - &sam_pass->kickoff_time, - &sam_pass->pass_last_set_time, - &sam_pass->pass_can_change_time, - &sam_pass->pass_must_change_time, - - sam_pass->nt_name , /* user_name */ - sam_pass->full_name , /* full_name */ - sam_pass->logon_script , /* logon_script */ - sam_pass->profile_path , /* profile_path */ - sam_pass->home_dir , /* home_dir */ - sam_pass->dir_drive , /* dir_drive */ + &logon_time, + &logoff_time, + &kickoff_time, + &pass_last_set_time, + &pass_can_change_time, + &pass_must_change_time, + + nt_name , /* user_name */ + full_name , /* full_name */ + logon_script , /* logon_script */ + profile_path , /* profile_path */ + home_dir , /* home_dir */ + dir_drive , /* dir_drive */ 0, /* logon_count */ 0, /* bad_pw_count */ - sam_pass->user_rid , /* RID user_id */ - sam_pass->group_rid , /* RID group_id */ + user_rid , /* RID user_id */ + group_rid , /* RID group_id */ num_gids, /* uint32 num_groups */ gids , /* DOM_GID *gids */ 0x20 , /* uint32 user_flgs (?) */ diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 1abb084124..505067c83e 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -60,6 +60,49 @@ static void overflow_attack(int len) } +/**************************************************************************** + does _both_ nt->unix and unix->unix username remappings. +****************************************************************************/ +static BOOL map_nt_and_unix_username(const char *domain, char *user) +{ + DOM_NAME_MAP gmep; + fstring nt_username; + + /* + * Pass the user through the NT -> unix user mapping + * function. + */ + + memset(nt_username, 0, sizeof(nt_username)); + if (domain != NULL) + { + slprintf(nt_username, sizeof(nt_username)-1, "%s\\%s", + domain, user); + } + else + { + fstrcpy(nt_username, user); + } + if (!lookupsmbpwntnam(nt_username, &gmep)) + { + return False; + } + + fstrcpy(user, gmep.unix_name); + + /* + * Pass the user through the unix -> unix user mapping + * function. + */ + + (void)map_username(user); + + /* + * Do any UNIX username case mangling. + */ + return Get_Pwnam( user, True) != NULL; +} + /**************************************************************************** reply to an special message ****************************************************************************/ @@ -220,17 +263,10 @@ int reply_tcon(connection_struct *conn, parse_connect(smb_buf(inbuf)+1,service,user,password,&pwlen,dev); - /* - * Pass the user through the NT -> unix user mapping - * function. - */ - - (void)map_username(user); - - /* - * Do any UNIX username case mangling. - */ - (void)Get_Pwnam( user, True); + if (!map_nt_and_unix_username(global_myworkgroup, user)) + { + return(connection_error(inbuf,outbuf,ERRbadpw)); + } conn = make_connection(service,user,password,pwlen,dev,vuid,&ecode); @@ -300,18 +336,11 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt StrnCpy(devicename,path + strlen(path) + 1,6); DEBUG(4,("Got device type %s\n",devicename)); - /* - * Pass the user through the NT -> unix user mapping - * function. - */ - - (void)map_username(user); - - /* - * Do any UNIX username case mangling. - */ - (void)Get_Pwnam(user, True); - + if (!map_nt_and_unix_username(global_myworkgroup, user)) + { + return(connection_error(inbuf,outbuf,ERRbadpw)); + } + conn = make_connection(service,user,password,passlen,devicename,vuid,&ecode); if (!conn) @@ -642,17 +671,10 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int pstrcpy( orig_user, user); - /* - * Pass the user through the NT -> unix user mapping - * function. - */ - - (void)map_username(user); - - /* - * Do any UNIX username case mangling. - */ - (void)Get_Pwnam( user, True); + if (!map_nt_and_unix_username(domain, user)) + { + return(ERROR(ERRSRV,ERRbadpw)); + } add_session_user(user); -- cgit