diff options
author | Luke Leighton <lkcl@samba.org> | 1998-11-29 20:06:52 +0000 |
---|---|---|
committer | Luke Leighton <lkcl@samba.org> | 1998-11-29 20:06:52 +0000 |
commit | 53373894acfff45885caf1e19a54141546ba5eea (patch) | |
tree | 7c4de230aa7357723f2858589142beed12f02156 /source3/passdb | |
parent | 30038de4623bc827ee8019c569faf00583d1fe58 (diff) | |
download | samba-53373894acfff45885caf1e19a54141546ba5eea.tar.gz samba-53373894acfff45885caf1e19a54141546ba5eea.tar.bz2 samba-53373894acfff45885caf1e19a54141546ba5eea.zip |
"retired" two modules to preserve their cvs history.
added their replacements, added sam password database API modules
(This used to be commit b1d1c1337c69c6f6bf25ab932a1a6a757e3ea2ae)
Diffstat (limited to 'source3/passdb')
-rw-r--r-- | source3/passdb/sampass.c | 198 | ||||
-rw-r--r-- | source3/passdb/sampassdb.c | 515 |
2 files changed, 713 insertions, 0 deletions
diff --git a/source3/passdb/sampass.c b/source3/passdb/sampass.c new file mode 100644 index 0000000000..967e0502e3 --- /dev/null +++ b/source3/passdb/sampass.c @@ -0,0 +1,198 @@ +/* + * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup + * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995. + * + * 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" + +#ifdef USE_SMBPASS_DB + +extern int DEBUGLEVEL; +extern pstring samlogon_user; +extern BOOL sam_logon_in_ssb; + +extern DOM_SID global_sam_sid; + +/*************************************************************** + Start to enumerate the smbpasswd list. Returns a void pointer + to ensure no modification outside this module. +****************************************************************/ + +void *startsamfilepwent(BOOL update) +{ + return startsmbpwent(update); +} + +/*************************************************************** + End enumeration of the smbpasswd list. +****************************************************************/ + +void endsamfilepwent(void *vp) +{ + endsmbpwent(vp); +} + +/************************************************************************* + Return the current position in the smbpasswd list as an SMB_BIG_UINT. + This must be treated as an opaque token. +*************************************************************************/ + +SMB_BIG_UINT getsamfilepwpos(void *vp) +{ + return getsmbpwpos(vp); +} + +/************************************************************************* + Set the current position in the smbpasswd list from an SMB_BIG_UINT. + This must be treated as an opaque token. +*************************************************************************/ + +BOOL setsamfilepwpos(void *vp, SMB_BIG_UINT tok) +{ + return setsmbpwpos(vp, tok); +} + +/************************************************************************* + Routine to return the next entry in the smbpasswd list. + this function is a nice, messy combination of reading: + - the smbpasswd file + - the unix password database + - smb.conf options (not done at present). + *************************************************************************/ + +static struct sam_passwd *getsamfile21pwent(void *vp) +{ + struct sam_passwd *user; + + static pstring full_name; + static pstring home_dir; + static pstring home_drive; + static pstring logon_script; + static pstring profile_path; + static pstring acct_desc; + static pstring workstations; + + DEBUG(5,("getsamfile21pwent\n")); + + user = pwdb_smb_to_sam(getsmbpwent(vp)); + if (user == NULL) + { + return NULL; + } + + /* + * get all the other gubbins we need + */ + + pstrcpy(samlogon_user, user->nt_name); + + if (samlogon_user[strlen(samlogon_user)-1] == '$' && + user->group_rid != DOMAIN_GROUP_RID_USERS) + { + DEBUG(0,("trust account %s should be in DOMAIN_GROUP_RID_USERS\n", + samlogon_user)); + } + + /* XXXX hack to get standard_sub_basic() to use sam logon username */ + /* possibly a better way would be to do a become_user() call */ + sam_logon_in_ssb = True; + + pstrcpy(full_name , ""); + pstrcpy(logon_script , lp_logon_script ()); + pstrcpy(profile_path , lp_logon_path ()); + pstrcpy(home_drive , lp_logon_drive ()); + pstrcpy(home_dir , lp_logon_home ()); + pstrcpy(acct_desc , ""); + pstrcpy(workstations , ""); + + sam_logon_in_ssb = False; + + user->full_name = full_name; + user->home_dir = home_dir; + user->dir_drive = home_drive; + user->logon_script = logon_script; + user->profile_path = profile_path; + user->acct_desc = acct_desc; + user->workstations = workstations; + + user->unknown_str = NULL; /* don't know, yet! */ + user->munged_dial = NULL; /* "munged" dial-back telephone number */ + + user->unknown_3 = 0xffffff; /* don't know */ + user->logon_divs = 168; /* hours per week */ + user->hours_len = 21; /* 21 times 8 bits = 168 */ + memset(user->hours, 0xff, user->hours_len); /* available at all hours */ + user->unknown_5 = 0x00020000; /* don't know */ + user->unknown_6 = 0x000004ec; /* don't know */ + + return user; +} + +/* + * Stub functions - implemented in terms of others. + */ + +static BOOL mod_samfile21pwd_entry(struct sam_passwd* pwd, BOOL override) +{ + return mod_smbpwd_entry(pwdb_sam_to_smb(pwd), override); +} + +static BOOL add_samfile21pwd_entry(struct sam_passwd *newpwd) +{ + return add_smbpwd_entry(pwdb_sam_to_smb(newpwd)); +} + +static struct sam_disp_info *getsamfiledispntnam(const char *name) +{ + return pwdb_sam_to_dispinfo(getsam21pwntnam(name)); +} + +static struct sam_disp_info *getsamfiledisprid(uint32 rid) +{ + return pwdb_sam_to_dispinfo(getsam21pwrid(rid)); +} + +static struct sam_disp_info *getsamfiledispent(void *vp) +{ + return pwdb_sam_to_dispinfo(getsam21pwent(vp)); +} + +static struct sam_passdb_ops file_ops = { + startsamfilepwent, + endsamfilepwent, + getsamfilepwpos, + setsamfilepwpos, + iterate_getsam21pwntnam, + iterate_getsam21pwuid, + iterate_getsam21pwrid, + getsamfile21pwent, + add_samfile21pwd_entry, + mod_samfile21pwd_entry, + getsamfiledispntnam, + getsamfiledisprid, + getsamfiledispent +}; + +struct sam_passdb_ops *file_initialise_sam_password_db(void) +{ + return &file_ops; +} + +#else + /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */ + void sampass_dummy_function(void) { } /* stop some compilers complaining */ +#endif /* USE_SMBPASS_DB */ diff --git a/source3/passdb/sampassdb.c b/source3/passdb/sampassdb.c new file mode 100644 index 0000000000..95055ed298 --- /dev/null +++ b/source3/passdb/sampassdb.c @@ -0,0 +1,515 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Password and authentication handling + Copyright (C) Jeremy Allison 1996-1998 + Copyright (C) Luke Kenneth Casson Leighton 1996-1998 + + 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" +#include "nterr.h" + +extern int DEBUGLEVEL; +extern DOM_SID global_sam_sid; + +/* + * NOTE. All these functions are abstracted into a structure + * that points to the correct function for the selected database. JRA. + * + * NOTE. for the get/mod/add functions, there are two sets of functions. + * one supports struct sam_passwd, the other supports struct smb_passwd. + * for speed optimisation it is best to support both these sets. + * + * it is, however, optional to support one set but not the other: there + * is conversion-capability built in to passdb.c, and run-time error + * detection for when neither are supported. + * + * password database writers are recommended to implement the sam_passwd + * functions in a first pass, as struct sam_passwd contains more + * information, needed by the NT Domain support. + * + * an API writer is expected to create either one set (struct smb_passwd) or + * the other (struct sam_passwd) OR both, and optionally also to write display + * info routines * (struct sam_disp_info). functions which the API writer + * chooses NOT to write must be wrapped in conversion functions (pwdb_x_to_y) + * such that API users can call any function and still get valid results. + * + * the password API does NOT fill in the gaps if you set an API function + * to NULL: it will deliberately attempt to call the NULL function. + * + */ + +static struct sam_passdb_ops *pwdb_ops; + +/*************************************************************** + Initialise the password db operations. +***************************************************************/ + +BOOL initialise_sam_password_db(void) +{ + if (pwdb_ops) + { + return True; + } + +#ifdef WITH_NISPLUS + pwdb_ops = nisplus_initialise_sam_password_db(); +#elif defined(WITH_LDAP) + pwdb_ops = ldap_initialise_sam_password_db(); +#elif defined(USE_SMBPASS_DB) + pwdb_ops = file_initialise_sam_password_db(); +#endif + + return (pwdb_ops != NULL); +} + +/* + * Functions that return/manipulate a struct sam_passwd. + */ + +/*************************************************************** + Start to enumerate the smb or sam passwd list. Returns a void pointer + to ensure no modification outside this module. + + Note that currently it is being assumed that a pointer returned + from this function may be used to enumerate struct sam_passwd + entries as well as struct smb_passwd entries. This may need + to change. JRA. + +****************************************************************/ + +void *startsam21pwent(BOOL update) +{ + return pwdb_ops->startsam21pwent(update); +} + +/*************************************************************** + End enumeration of the sam passwd list. + + Note that currently it is being assumed that a pointer returned + from this function may be used to enumerate struct sam_passwd + entries as well as struct smb_passwd entries. This may need + to change. JRA. + +****************************************************************/ + +void endsam21pwent(void *vp) +{ + pwdb_ops->endsam21pwent(vp); +} + +/************************************************************************* + Routine to return the next entry in the smb passwd list. + *************************************************************************/ + +struct sam_passwd *getsam21pwent(void *vp) +{ + return pwdb_sam_map_names(pwdb_ops->getsam21pwent(vp)); +} + +/************************************************************************ + Utility function to search sam passwd by name. use this if your database + does not have search facilities. +*************************************************************************/ + +struct sam_passwd *iterate_getsam21pwntnam(const char *name) +{ + struct sam_passwd *pwd = NULL; + void *fp = NULL; + + DEBUG(10, ("search by name: %s\n", name)); + + /* Open the smb password database - not for update. */ + fp = startsmbpwent(False); + + if (fp == NULL) + { + DEBUG(0, ("unable to open sam password database.\n")); + return NULL; + } + + while ((pwd = getsam21pwent(fp)) != NULL && !strequal(pwd->nt_name, 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)); + } + + endsmbpwent(fp); + return pwd; +} + +/************************************************************************ + Utility function to search sam passwd by rid. use this if your database + does not have search facilities. + + search capability by both rid and uid are needed as the rid <-> uid + mapping may be non-monotonic. + +*************************************************************************/ + +struct sam_passwd *iterate_getsam21pwrid(uint32 rid) +{ + struct sam_passwd *pwd = NULL; + void *fp = NULL; + + DEBUG(10, ("search by rid: %x\n", rid)); + + /* Open the smb password file - not for update. */ + fp = startsmbpwent(False); + + if (fp == NULL) + { + DEBUG(0, ("unable to open sam password database.\n")); + return NULL; + } + + while ((pwd = getsam21pwent(fp)) != NULL && pwd->user_rid != rid) + { + DEBUG(10, ("iterate: %s 0x%x\n", pwd->nt_name, pwd->user_rid)); + } + + if (pwd != NULL) + { + DEBUG(10, ("found by user_rid: %x\n", rid)); + } + + endsmbpwent(fp); + return pwd; +} + +/************************************************************************ + Utility function to search sam passwd by uid. use this if your database + does not have search facilities. + + search capability by both rid and uid are needed as the rid <-> uid + mapping may be non-monotonic. + +*************************************************************************/ + +struct sam_passwd *iterate_getsam21pwuid(uid_t uid) +{ + struct sam_passwd *pwd = NULL; + void *fp = NULL; + + DEBUG(10, ("search by uid: %x\n", (int)uid)); + + /* Open the smb password file - not for update. */ + fp = startsmbpwent(False); + + if (fp == NULL) + { + DEBUG(0, ("unable to open sam password database.\n")); + return NULL; + } + + while ((pwd = getsam21pwent(fp)) != NULL && pwd->unix_uid != uid) + { + } + + if (pwd != NULL) + { + DEBUG(10, ("found by unix_uid: %x\n", (int)uid)); + } + + endsmbpwent(fp); + return pwd; +} + +/************************************************************************* + Routine to return a display info structure, by rid + *************************************************************************/ +struct sam_disp_info *getsamdisprid(uint32 rid) +{ + return pwdb_ops->getsamdisprid(rid); +} + +/************************************************************************ + Routine to search sam passwd by name. +*************************************************************************/ + +struct sam_passwd *getsam21pwntnam(const char *name) +{ + return pwdb_sam_map_names(pwdb_ops->getsam21pwntnam(name)); +} + +/************************************************************************ + Routine to search sam passwd by rid. +*************************************************************************/ + +struct sam_passwd *getsam21pwrid(uint32 rid) +{ + return pwdb_sam_map_names(pwdb_ops->getsam21pwrid(rid)); +} + + +/********************************************************** + ********************************************************** + + utility routines which are likely to be useful to all password + databases + + ********************************************************** + **********************************************************/ + +/************************************************************* + initialises a struct sam_disp_info. + **************************************************************/ + +static void pwdb_init_dispinfo(struct sam_disp_info *user) +{ + if (user == NULL) return; + bzero(user, sizeof(*user)); + user->user_rid = 0xffffffff; +} + +/************************************************************* + initialises a struct sam_passwd. + **************************************************************/ +void pwdb_init_sam(struct sam_passwd *user) +{ + if (user == NULL) return; + bzero(user, sizeof(*user)); + unix_to_nt_time(&user->logon_time , (time_t)-1); + unix_to_nt_time(&user->logoff_time , (time_t)-1); + unix_to_nt_time(&user->kickoff_time , (time_t)-1); + unix_to_nt_time(&user->pass_last_set_time , (time_t)-1); + unix_to_nt_time(&user->pass_can_change_time , (time_t)-1); + unix_to_nt_time(&user->pass_must_change_time , (time_t)-1); + + user->unix_uid = (uid_t)-1; + user->unix_gid = (gid_t)-1; + user->user_rid = 0xffffffff; + user->group_rid = 0xffffffff; +} + +/************************************************************************* + Routine to return the next entry in the sam passwd list. + *************************************************************************/ + +struct sam_disp_info *pwdb_sam_to_dispinfo(struct sam_passwd *user) +{ + static struct sam_disp_info disp_info; + + if (user == NULL) return NULL; + + pwdb_init_dispinfo(&disp_info); + + disp_info.nt_name = user->nt_name; + disp_info.full_name = user->full_name; + disp_info.user_rid = user->user_rid; + + return &disp_info; +} + +/************************************************************* + converts a sam_passwd structure to a smb_passwd structure. + **************************************************************/ + +struct smb_passwd *pwdb_sam_to_smb(struct sam_passwd *user) +{ + static struct smb_passwd pw_buf; + static fstring nt_name; + static fstring unix_name; + + if (user == NULL) return NULL; + + pwdb_init_smb(&pw_buf); + + fstrcpy(nt_name , user->nt_name); + fstrcpy(unix_name, user->unix_name); + pw_buf.nt_name = nt_name; + pw_buf.unix_name = unix_name; + pw_buf.unix_uid = user->unix_uid; + pw_buf.user_rid = user->user_rid; + pw_buf.smb_passwd = user->smb_passwd; + pw_buf.smb_nt_passwd = user->smb_nt_passwd; + pw_buf.acct_ctrl = user->acct_ctrl; + pw_buf.pass_last_set_time = nt_time_to_unix(&user->pass_last_set_time); + + return &pw_buf; +} + + +/************************************************************* + converts a smb_passwd structure to a sam_passwd structure. + **************************************************************/ + +struct sam_passwd *pwdb_smb_to_sam(struct smb_passwd *user) +{ + static struct sam_passwd pw_buf; + static fstring nt_name; + static fstring unix_name; + + if (user == NULL) return NULL; + + pwdb_init_sam(&pw_buf); + + fstrcpy(nt_name , user->nt_name); + fstrcpy(unix_name, user->unix_name); + pw_buf.nt_name = nt_name; + pw_buf.unix_name = unix_name; + pw_buf.unix_uid = user->unix_uid; + pw_buf.user_rid = user->user_rid; + pw_buf.smb_passwd = user->smb_passwd; + pw_buf.smb_nt_passwd = user->smb_nt_passwd; + pw_buf.acct_ctrl = user->acct_ctrl; + unix_to_nt_time(&pw_buf.pass_last_set_time, user->pass_last_set_time); + + return &pw_buf; +} + +static BOOL trust_account_warning_done = False; + +/************************************************************* + fills in missing details. one set of details _must_ exist. + **************************************************************/ +struct sam_passwd *pwdb_sam_map_names(struct sam_passwd *sam) +{ + DOM_NAME_MAP gmep; + BOOL found = False; + DOM_SID sid; + static fstring unix_name; + static fstring nt_name; + + DEBUG(10,("pwdb_sam_map_names\n")); + + /* + * name details + */ + + if (sam == NULL) + { + return NULL; + } + + if (!found && sam->unix_name != NULL) + { + found = lookupsmbpwnam(sam->unix_name, &gmep); + } + if (!found && sam->unix_uid != (uid_t)-1) + { + found = lookupsmbpwuid(sam->unix_uid , &gmep); + } + if (!found && sam->user_rid != 0xffffffff) + { + sid_copy(&sid, &global_sam_sid); + sid_append_rid(&sid, sam->user_rid); + found = lookupsmbpwsid (&sid , &gmep); + } + if (!found && sam->nt_name != NULL) + { + found = lookupsmbpwntnam(sam->nt_name, &gmep); + } + + if (!found) + { + return NULL; + } + + if (!sid_front_equal(&global_sam_sid, &gmep.sid)) + { + return NULL; + } + + fstrcpy(unix_name, gmep.unix_name); + fstrcpy(nt_name , gmep.nt_name ); + if (sam->unix_name == NULL ) sam->unix_name = unix_name; + if (sam->nt_name == NULL ) sam->nt_name = nt_name ; + 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); + + /* + * group details + */ + + found = False; + + if (sam->unix_gid != (gid_t)-1 && sam->group_rid != 0xffffffff) + { + return sam; + } + + if (sam->unix_gid == (gid_t)-1 && sam->group_rid == 0xffffffff) + { + struct passwd *pass = getpwnam(unix_name); + if (pass != NULL) + { + sam->unix_gid = pass->pw_gid; + } + else + { + DEBUG(0,("pwdb_sam_map_names: no unix password entry for %s\n", + unix_name)); + } + } + + if (!found && sam->unix_gid != (gid_t)-1) + { + found = lookupsmbgrpgid(sam->unix_gid , &gmep); + } + if (!found && sam->group_rid != 0xffffffff) + { + sid_copy(&sid, &global_sam_sid); + sid_append_rid(&sid, sam->group_rid); + found = lookupsmbgrpsid(&sid , &gmep); + } + + if (!found) + { + if (IS_BITS_SET_SOME(sam->acct_ctrl, ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) + { + if (!trust_account_warning_done) + { + trust_account_warning_done = True; + DEBUG(0, ("\ +pwdb_sam_map_names: your unix password database appears to have difficulties\n\ +resolving trust account %s, probably because it ends in a '$'.\n\ +you will get this warning only once (for all trust accounts)\n", unix_name)); + } + /* + * oh, dear. + */ + if (sam->unix_gid != (gid_t)-1) + { + sam->unix_gid = (gid_t)-1; + } + sam->group_rid = DOMAIN_GROUP_RID_USERS; + + return sam; + } + else + { + DEBUG(0, ("pwdb_sam_map_names: could not find Primary Group for %s\n", + unix_name)); + return NULL; + } + } + + if (!sid_front_equal(&global_sam_sid, &gmep.sid)) + { + return NULL; + } + + 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); + + return sam; +} |