summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2002-08-20 20:56:10 +0000
committerJelmer Vernooij <jelmer@samba.org>2002-08-20 20:56:10 +0000
commit2e01bef42db414b61e696829603c5e1c8a36aac5 (patch)
tree42767c7ba2e496929539891d30f2ab101f6f76b6
parentf744db7a5dee0764bb41c43336b1b1a933a79682 (diff)
downloadsamba-2e01bef42db414b61e696829603c5e1c8a36aac5.tar.gz
samba-2e01bef42db414b61e696829603c5e1c8a36aac5.tar.bz2
samba-2e01bef42db414b61e696829603c5e1c8a36aac5.zip
pdb_nisplus converted to the new passdb system API's
(This used to be commit 72e9a5cd340d6a912e274dc0d6f2a22a922d4b03)
-rw-r--r--source3/passdb/pdb_interface.c1
-rw-r--r--source3/passdb/pdb_nisplus.c1144
2 files changed, 586 insertions, 559 deletions
diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c
index f311223d77..f5926e54f1 100644
--- a/source3/passdb/pdb_interface.c
+++ b/source3/passdb/pdb_interface.c
@@ -34,6 +34,7 @@ const struct pdb_init_function_entry builtin_pdb_init_functions[] = {
{ "ldapsam", pdb_init_ldapsam },
{ "ldapsam_nua", pdb_init_ldapsam_nua },
{ "unixsam", pdb_init_unixsam },
+ { "nisplussam", pdb_init_nisplussam },
{ "plugin", pdb_init_plugin },
{ NULL, NULL}
};
diff --git a/source3/passdb/pdb_nisplus.c b/source3/passdb/pdb_nisplus.c
index 2d37c3b8fb..c302691bec 100644
--- a/source3/passdb/pdb_nisplus.c
+++ b/source3/passdb/pdb_nisplus.c
@@ -1,10 +1,10 @@
/*
- * Unix SMB/CIFS implementation.
- * SMB parameters and setup
+ * Test password backend for samba
* Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
* Copyright (C) Benny Holmgren 1998 <bigfoot@astrakan.hgs.se>
* Copyright (C) Luke Kenneth Casson Leighton 1996-1998.
* Copyright (C) Toomas Soome <tsoome@ut.ee> 2001
+ * Copyright (C) Jelmer Vernooij 2002
*
* 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
@@ -35,6 +35,7 @@
* an enum in /usr/include/rpcsvc/nis.h.
*/
+
#if defined(GROUP)
#undef GROUP
#endif
@@ -47,17 +48,6 @@
#include <rpcsvc/nis.h>
-extern int DEBUGLEVEL;
-
-struct nisp_enum_info
-{
- nis_result *result;
- int enum_entry;
-};
-
-static struct nisp_enum_info global_nisp_ent;
-static SIG_ATOMIC_T gotalarm;
-
/***************************************************************
the fields for the NIS+ table, generated from mknissmbpwtbl.sh, are:
@@ -114,16 +104,577 @@ static SIG_ATOMIC_T gotalarm;
#define NPF_WORKSTATIONS 20
#define NPF_HOURS 21
+struct nisp_enum_info
+{
+ nis_result *result;
+ int enum_entry;
+};
-/*******************************************************************
- Converts NT user RID to a UNIX uid.
- ********************************************************************/
+static char *make_nisname_from_user_rid(uint32 rid, char *pfile);
+static char *make_nisname_from_name(const char *user_name, char *pfile);
+static void get_single_attribute(const nis_object *new_obj, int col,
+ char *val, int len);;
+static BOOL make_sam_from_nisp_object(SAM_ACCOUNT *pw_buf, const nis_object *obj);
+static BOOL make_sam_from_nisresult(SAM_ACCOUNT *pw_buf, const nis_result *result);;
+static void set_single_attribute(nis_object *new_obj, int col,
+ const char *val, int len, int flags);
+static BOOL init_nisp_from_sam(nis_object *obj, const SAM_ACCOUNT *sampass,
+ nis_object *old);
+static nis_result *nisp_get_nis_list(const char *nisname, unsigned int flags);
+
+/***************************************************************
+ Start enumeration of the passwd list.
+****************************************************************/
+
+static BOOL nisplussam_setsampwent(struct pdb_methods *methods, BOOL update)
+{
+ struct nisp_enum_info *global_nisp_ent = (struct nisp_enum_info *)methods->private_data;
+
+ char *sp, * p = lp_smb_passwd_file();
+ pstring pfiletmp;
+
+ if( (sp = strrchr( p, '/' )) )
+ safe_strcpy(pfiletmp, sp+1, sizeof(pfiletmp)-1);
+ else
+ safe_strcpy(pfiletmp, p, sizeof(pfiletmp)-1);
+ safe_strcat(pfiletmp, ".org_dir", sizeof(pfiletmp)-strlen(pfiletmp)-1);
+
+ pdb_endsampwent(); /* just in case */
+ global_nisp_ent->result = nisp_get_nis_list( pfiletmp, 0 );
+ global_nisp_ent->enum_entry = 0;
+ return global_nisp_ent->result != NULL ? True : False;
+}
+
+/***************************************************************
+ End enumeration of the passwd list.
+****************************************************************/
+
+static void nisplussam_endsampwent(struct pdb_methods *methods)
+{
+ struct nisp_enum_info *global_nisp_ent = (struct nisp_enum_info *)methods->private_data;
+ if( global_nisp_ent->result )
+ nis_freeresult(global_nisp_ent->result);
+ global_nisp_ent->result = NULL;
+ global_nisp_ent->enum_entry = 0;
+}
+
+/*****************************************************************
+ Get one SAM_ACCOUNT from the list (next in line)
+*****************************************************************/
+
+static BOOL nisplussam_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT *user)
+{
+
+ struct nisp_enum_info *global_nisp_ent = (struct nisp_enum_info *)methods->private_data;
+ int enum_entry = (int)(global_nisp_ent->enum_entry);
+ nis_result *result = global_nisp_ent->result;
+
+ if (user==NULL) {
+ DEBUG(0,("SAM_ACCOUNT is NULL.\n"));
+ return False;
+ }
+
+ if (result == NULL ||
+ enum_entry < 0 || enum_entry >= (NIS_RES_NUMOBJ(result) - 1))
+ {
+ return False;
+ }
+
+ if(!make_sam_from_nisp_object(user, &NIS_RES_OBJECT(result)[enum_entry]) )
+ {
+ DEBUG(0,("Bad SAM_ACCOUNT entry returned from NIS+!\n"));
+ return False;
+ }
+ (int)(global_nisp_ent->enum_entry)++;
+ return True;
+ DEBUG(10, ("nisplussam_getsampwent called\n"));
+ return False;
+}
+
+/******************************************************************
+ Lookup a name in the SAM database
+******************************************************************/
+
+static BOOL nisplussam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname)
+{
+ /* Static buffers we will return. */
+ nis_result *result = NULL;
+ pstring nisname;
+ BOOL ret;
+ char *pfile = lp_smb_passwd_file();
+
+ if (!*pfile)
+ {
+ DEBUG(0, ("No SMB password file set\n"));
+ return False;
+ }
+ if( strrchr( pfile, '/') )
+ pfile = strrchr( pfile, '/') + 1;
+
+ slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.org_dir", sname, pfile);
+ DEBUG(10, ("search by nisname: %s\n", nisname));
+
+ /* Search the table. */
+
+ if(!(result = nisp_get_nis_list(nisname, 0)))
+ {
+ return False;
+ }
+
+ ret = make_sam_from_nisresult(user, result);
+ nis_freeresult(result);
+
+ return ret;
+
+ DEBUG(10, ("nisplussam_getsampwnam called\n"));
+ return False;
+}
+
+/***************************************************************************
+ Search by sid
+ **************************************************************************/
+
+static BOOL nisplussam_getsampwrid (struct pdb_methods *methods, SAM_ACCOUNT *user, uint32 rid)
+{
+ nis_result *result;
+ char *nisname;
+ BOOL ret;
+ char *sp, *p = lp_smb_passwd_file();
+ pstring pfiletmp;
+
+ if (!*p)
+ {
+ DEBUG(0, ("no SMB password file set\n"));
+ return False;
+ }
+
+ if( (sp = strrchr( p, '/' )) )
+ safe_strcpy(pfiletmp, sp+1, sizeof(pfiletmp)-1);
+ else
+ safe_strcpy(pfiletmp, p, sizeof(pfiletmp)-1);
+ safe_strcat(pfiletmp, ".org_dir", sizeof(pfiletmp)-strlen(pfiletmp)-1);
+
+ nisname = make_nisname_from_user_rid(rid, pfiletmp);
+
+ DEBUG(10, ("search by rid: %s\n", nisname));
+
+ /* Search the table. */
+
+ if(!(result = nisp_get_nis_list(nisname, 0)))
+ {
+ return False;
+ }
+
+ ret = make_sam_from_nisresult(user, result);
+ nis_freeresult(result);
+
+ return ret;
+
+ DEBUG(10, ("nisplussam_getsampwsid called\n"));
+ return False;
+}
+
+static BOOL nisplussam_getsampwsid (struct pdb_methods *methods, SAM_ACCOUNT *user, const DOM_SID *sid)
+{
+ uint32 rid;
+ if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) return False;
+ return nisplussam_getsampwrid(methods, user, rid);
+}
+
+
+
+/***************************************************************************
+ Delete a SAM_ACCOUNT
+****************************************************************************/
+
+static BOOL nisplussam_delete_sam_account(struct pdb_methods *methods, SAM_ACCOUNT *user)
+{
+
+ const char *sname;
+ char *pfile = lp_smb_passwd_file();
+ pstring nisname;
+ nis_result *result, *delresult;
+ nis_object *obj;
+
+ if (!user) {
+ DEBUG(0, ("no SAM_ACCOUNT specified!\n"));
+ return False;
+ }
+
+ sname = pdb_get_username(user);
+
+ if (!*pfile)
+ {
+ DEBUG(0, ("no SMB password file set\n"));
+ return False;
+ }
+ if( strrchr( pfile, '/') )
+ pfile = strrchr( pfile, '/') + 1;
+
+ slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.org_dir", sname, pfile);
+
+ /* Search the table. */
+
+ if( !(result = nisp_get_nis_list(nisname,
+ MASTER_ONLY|FOLLOW_LINKS|FOLLOW_PATH|\
+ EXPAND_NAME|HARD_LOOKUP))) {
+ return False;
+ }
+
+ if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) {
+ /* User not found. */
+ DEBUG(0,("user not found in NIS+\n"));
+ nis_freeresult(result);
+ return False;
+ }
+
+ obj = NIS_RES_OBJECT(result);
+ slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.%s", sname, obj->zo_name,
+ obj->zo_domain);
+
+ DEBUG(10, ("removing name: %s\n", nisname));
+ delresult = nis_remove_entry(nisname, obj,
+ MASTER_ONLY|REM_MULTIPLE|ALL_RESULTS|FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
+
+ nis_freeresult(result);
+
+ if(delresult->status != NIS_SUCCESS) {
+ DEBUG(0, ("NIS+ table update failed: %s %s\n",
+ nisname, nis_sperrno(delresult->status)));
+ nis_freeresult(delresult);
+ return False;
+ }
+ nis_freeresult(delresult);
+ return True;
+ DEBUG(10, ("nisplussam_delete_sam_account called\n"));
+ return False;
+}
+
+/***************************************************************************
+ Modifies an existing SAM_ACCOUNT
+****************************************************************************/
+
+static BOOL nisplussam_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
+{
+ nis_result *result, *addresult;
+ nis_object *obj;
+ nis_object new_obj;
+ entry_col *ecol;
+ int ta_maxcol;
+ char *pfile = lp_smb_passwd_file();
+ pstring nisname;
+
+ if (!*pfile)
+ {
+ DEBUG(0, ("no SMB password file set\n"));
+ return False;
+ }
+ if( strrchr( pfile, '/') )
+ pfile = strrchr( pfile, '/') + 1;
+
+ slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.org_dir",
+ pdb_get_username(newpwd), pfile);
+
+ DEBUG(10, ("search by name: %s\n", nisname));
+
+ /* Search the table. */
+
+ if( !(result = nisp_get_nis_list(nisname, MASTER_ONLY|FOLLOW_LINKS|\
+ FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP))) {
+ return False;
+ }
+
+ if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) {
+ /* User not found. */
+ DEBUG(0,("user not found in NIS+\n"));
+ nis_freeresult(result);
+ return False;
+ }
+
+ obj = NIS_RES_OBJECT(result);
+ DEBUG(6,("entry found in %s\n", obj->zo_domain));
+
+ /* we must create new stub object with EN_MODIFIED flag.
+ this is because obj from result is going to be freed and
+ we do not want to break it or cause memory leaks or corruption.
+ */
+
+ memmove((char *)&new_obj, obj, sizeof (new_obj));
+ ta_maxcol = obj->TA_data.ta_maxcol;
+
+ if(!(ecol = (entry_col*)malloc(ta_maxcol*sizeof(entry_col)))) {
+ DEBUG(0, ("memory allocation failure\n"));
+ nis_freeresult(result);
+ return False;
+ }
+
+ memmove((char *)ecol, obj->EN_data.en_cols.en_cols_val,
+ ta_maxcol*sizeof (entry_col));
+ new_obj.EN_data.en_cols.en_cols_val = ecol;
+ new_obj.EN_data.en_cols.en_cols_len = ta_maxcol;
+
+ if ( init_nisp_from_sam(&new_obj, newpwd, obj) == True ) {
+ slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.%s",
+ pdb_get_username(newpwd), pfile, obj->zo_domain);
+
+ DEBUG(10, ("NIS+ table update: %s\n", nisname));
+ addresult =
+ nis_modify_entry(nisname, &new_obj,
+ MOD_SAMEOBJ | FOLLOW_PATH | EXPAND_NAME | HARD_LOOKUP);
+
+ if(addresult->status != NIS_SUCCESS) {
+ DEBUG(0, ("NIS+ table update failed: %s %s\n",
+ nisname, nis_sperrno(addresult->status)));
+ nis_freeresult(addresult);
+ nis_freeresult(result);
+ free(ecol);
+ return False;
+ }
+
+ DEBUG(6,("password changed\n"));
+ nis_freeresult(addresult);
+ } else {
+ DEBUG(6,("nothing to change!\n"));
+ }
+
+ free(ecol);
+ nis_freeresult(result);
+
+ return True;
+
+ DEBUG(10, ("nisplussam_update_sam_account called\n"));
+ return False;
+}
+
+/***************************************************************************
+ Adds an existing SAM_ACCOUNT
+****************************************************************************/
+
+static BOOL nisplussam_add_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
+{
+ int local_user = 0;
+ char *pfile;
+ pstring pfiletmp;
+ char *nisname;
+ nis_result *result = NULL,
+ *tblresult = NULL;
+ nis_object new_obj;
+ entry_col *ecol;
+ int ta_maxcol;
+
+ /*
+ * 1. find user domain.
+ * a. try nis search in passwd.org_dir - if found use domain from result.
+ * b. try getpwnam. this may be needed if user is defined
+ * in /etc/passwd file (or elsewere) and not in passwd.org_dir.
+ * if found, use host default domain.
+ * c. exit with False - no such user.
+ *
+ * 2. add user
+ * a. find smbpasswd table
+ * search pfile in user domain if not found, try host default
+ * domain.
+ * b. smbpasswd domain is found, fill data and add entry.
+ *
+ * pfile should contain ONLY table name, org_dir will be concated.
+ * so, at first we will clear path prefix from pfile, and
+ * then we will use pfiletmp as playground to put together full
+ * nisname string.
+ * such approach will make it possible to specify samba private dir
+ * AND still use NIS+ table. as all domain related data is normally
+ * stored in org_dir.DOMAIN, this should be ok do do.
+ */
+
+ pfile = lp_smb_passwd_file();
+ if( strrchr( pfile, '/') )
+ pfile = strrchr( pfile, '/') + 1;
+
+ /*
+ * Check if user is already there.
+ */
+ safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
+ safe_strcat(pfiletmp, ".org_dir",
+ sizeof(pfiletmp)-strlen(pfiletmp)-1);
+
+ if(pdb_get_username(newpwd) != NULL) {
+ nisname = make_nisname_from_name(pdb_get_username(newpwd),
+ pfiletmp);
+ } else {
+ return False;
+ }
+
+ if(!(result = nisp_get_nis_list(nisname, MASTER_ONLY|FOLLOW_LINKS|\
+ FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP))) {
+ return False;
+ }
+ if (result->status != NIS_SUCCESS &&
+ result->status != NIS_NOTFOUND) {
+ DEBUG(3, ( "nis_list failure: %s: %s\n",
+ nisname, nis_sperrno(result->status)));
+ nis_freeresult(result);
+ return False;
+ }
+
+ if (result->status == NIS_SUCCESS && NIS_RES_NUMOBJ(result) > 0)
+ {
+ DEBUG(3, ("User already exists in NIS+ password db: %s\n",
+ pfile));
+ nis_freeresult(result);
+ return False;
+ }
+
+ nis_freeresult(result); /* no such user, free results */
+
+ /*
+ * check for user in unix password database. we need this to get
+ * domain, where smbpasswd entry should be stored.
+ */
+
+ nisname = make_nisname_from_name(pdb_get_username(newpwd),
+ "passwd.org_dir");
+
+ result = nisp_get_nis_list(nisname,
+ MASTER_ONLY|FOLLOW_LINKS|FOLLOW_PATH|\
+ EXPAND_NAME|HARD_LOOKUP);
+
+ if (result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0)
+ {
+ struct passwd *passwd;
+ DEBUG(3, ("nis_list failure: %s: %s\n",
+ nisname, nis_sperrno(result->status)));
+ nis_freeresult(result);
+
+ if (!(passwd = getpwnam_alloc(pdb_get_username(newpwd)))) {
+ /* no such user in system! */
+ return False;
+ }
+ passwd_free(&passwd);
+
+ /*
+ * user is defined, but not in passwd.org_dir.
+ */
+ local_user = 1;
+ } else {
+ safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
+ safe_strcat(pfiletmp, ".", sizeof(pfiletmp)-strlen(pfiletmp)-1);
+ safe_strcat(pfiletmp, NIS_RES_OBJECT(result)->zo_domain,
+ sizeof(pfiletmp)-strlen(pfiletmp)-1);
+ nis_freeresult(result); /* not needed any more */
+
+ tblresult = nisp_get_nis_list(pfiletmp,
+ MASTER_ONLY|FOLLOW_LINKS|\
+ FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
+ }
+
+ if (local_user || tblresult->status != NIS_SUCCESS)
+ {
+ /*
+ * no user domain or
+ * smbpasswd table not found in user domain, fallback to
+ * default domain.
+ */
+ if (!local_user) /* free previous failed search result */
+ nis_freeresult(tblresult);
+
+ safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
+ safe_strcat(pfiletmp, ".org_dir",
+ sizeof(pfiletmp)-strlen(pfiletmp)-1);
+ tblresult = nis_lookup(pfiletmp, MASTER_ONLY|FOLLOW_LINKS|\
+ FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
+ if (tblresult->status != NIS_SUCCESS)
+ {
+ /* still nothing. bail out */
+ nis_freeresult(tblresult);
+ DEBUG(3, ( "nis_lookup failure: %s\n",
+ nis_sperrno(tblresult->status)));
+ return False;
+ }
+ /* we need full name for nis_add_entry() */
+ safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
+ safe_strcat(pfiletmp, ".", sizeof(pfiletmp)-strlen(pfiletmp)-1);
+ safe_strcat(pfiletmp, NIS_RES_OBJECT(tblresult)->zo_domain,
+ sizeof(pfiletmp)-strlen(pfiletmp)-1);
+ }
+
+ memset((char *)&new_obj, 0, sizeof (new_obj));
+ /* fill entry headers */
+ /* we do not free these. */
+ new_obj.zo_name = NIS_RES_OBJECT(tblresult)->zo_name;
+ new_obj.zo_owner = NIS_RES_OBJECT(tblresult)->zo_owner;
+ new_obj.zo_group = NIS_RES_OBJECT(tblresult)->zo_group;
+ new_obj.zo_domain = NIS_RES_OBJECT(tblresult)->zo_domain;
+ /* uints */
+ new_obj.zo_access = NIS_RES_OBJECT(tblresult)->zo_access;
+ new_obj.zo_ttl = NIS_RES_OBJECT(tblresult)->zo_ttl;
+
+ new_obj.zo_data.zo_type = ENTRY_OBJ;
+ new_obj.EN_data.en_type =
+ NIS_RES_OBJECT(tblresult)->TA_data.ta_type;
+
+ ta_maxcol = NIS_RES_OBJECT(tblresult)->TA_data.ta_maxcol;
+
+ if(!(ecol = (entry_col*)malloc(ta_maxcol*sizeof(entry_col)))) {
+ DEBUG(0, ("memory allocation failure\n"));
+ nis_freeresult(tblresult);
+ return False;
+ }
+
+ memset((char *)ecol, 0, ta_maxcol*sizeof (entry_col));
+ new_obj.EN_data.en_cols.en_cols_val = ecol;
+ new_obj.EN_data.en_cols.en_cols_len = ta_maxcol;
+
+ init_nisp_from_sam(&new_obj, newpwd, NULL);
+
+ DEBUG(10, ( "add NIS+ entry: %s\n", nisname));
+ result = nis_add_entry(pfiletmp, &new_obj, 0);
+
+ free(ecol); /* free allocated entry space */
+
+ if (result->status != NIS_SUCCESS)
+ {
+ DEBUG(3, ( "NIS+ table update failed: %s,%s\n",
+ nisname, nis_sperrno(result->status)));
+ nis_freeresult(tblresult);
+ nis_freeresult(result);
+ return False;
+ }
+
+ nis_freeresult(tblresult);
+ nis_freeresult(result);
+
+ return True;
+
+ DEBUG(10, ("nisplussam_add_sam_account called\n"));
+ return False;
+}
-static uid_t pdb_user_rid_to_uid(uint32 user_rid)
+NTSTATUS pdb_init_nisplussam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
{
- return (uid_t)(((user_rid & (~USER_RID_TYPE))- 1000)/RID_MULTIPLIER);
+ NTSTATUS nt_status;
+
+ if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
+ return nt_status;
+ }
+
+ (*pdb_method)->name = "nisplussam";
+
+ /* Functions your pdb module doesn't provide should be set
+ * to NULL */
+
+ (*pdb_method)->setsampwent = nisplussam_setsampwent;
+ (*pdb_method)->endsampwent = nisplussam_endsampwent;
+ (*pdb_method)->getsampwent = nisplussam_getsampwent;
+ (*pdb_method)->getsampwnam = nisplussam_getsampwnam;
+ (*pdb_method)->getsampwsid = nisplussam_getsampwsid;
+ (*pdb_method)->add_sam_account = nisplussam_add_sam_account;
+ (*pdb_method)->update_sam_account = nisplussam_update_sam_account;
+ (*pdb_method)->delete_sam_account = nisplussam_delete_sam_account;
+ (*pdb_method)->private_data = malloc(sizeof(struct nisp_enum_info));
+
+ return NT_STATUS_OK;
}
+
/*******************************************************************
converts UNIX uid to an NT User RID.
********************************************************************/
@@ -134,14 +685,6 @@ static uint32 pdb_uid_to_user_rid(uid_t uid)
}
/***************************************************************
- Signal function to tell us we timed out.
-****************************************************************/
-static void gotalarm_sig(void)
-{
- gotalarm = 1;
-}
-
-/***************************************************************
make_nisname_from_user_rid
****************************************************************/
static char *make_nisname_from_user_rid(uint32 rid, char *pfile)
@@ -157,21 +700,6 @@ static char *make_nisname_from_user_rid(uint32 rid, char *pfile)
}
/***************************************************************
- make_nisname_from_uid
- ****************************************************************/
-static char *make_nisname_from_uid(int uid, char *pfile)
-{
- static pstring nisname;
-
- safe_strcpy(nisname, "[uid=", sizeof(nisname)-1);
- slprintf(nisname, sizeof(nisname)-1, "%s%d", nisname, uid);
- safe_strcat(nisname, "],", sizeof(nisname)-strlen(nisname)-1);
- safe_strcat(nisname, pfile, sizeof(nisname)-strlen(nisname)-1);
-
- return nisname;
-}
-
-/***************************************************************
make_nisname_from_name
****************************************************************/
static char *make_nisname_from_name(const char *user_name, char *pfile)
@@ -750,14 +1278,14 @@ static BOOL init_nisp_from_sam(nis_object *obj, const SAM_ACCOUNT *sampass,
/* logon_script */
/* must support set, unset and change */
- if( (pdb_get_logon_script(sampass) &&
- !ENTRY_VAL(old, NPF_LOGON_SCRIPT) ||
- (ENTRY_VAL(old, NPF_LOGON_SCRIPT) &&
- !pdb_get_logon_script(sampass)) ||
- ( ENTRY_VAL(old, NPF_LOGON_SCRIPT) &&
+ if( ((pdb_get_logon_script(sampass) &&
+ !ENTRY_VAL(old, NPF_LOGON_SCRIPT)) ||
+ ((ENTRY_VAL(old, NPF_LOGON_SCRIPT) &&
+ (!pdb_get_logon_script(sampass)))) ||
+ (( ENTRY_VAL(old, NPF_LOGON_SCRIPT) &&
pdb_get_logon_script(sampass) &&
strcmp( ENTRY_VAL(old, NPF_LOGON_SCRIPT),
- pdb_get_logon_script(sampass))))) {
+ pdb_get_logon_script(sampass)))))) {
need_to_modify = True;
set_single_attribute(obj, NPF_LOGON_SCRIPT,
pdb_get_logon_script(sampass),
@@ -803,9 +1331,9 @@ static BOOL init_nisp_from_sam(nis_object *obj, const SAM_ACCOUNT *sampass,
(ENTRY_VAL(old, NPF_WORKSTATIONS) &&
!pdb_get_workstations(sampass)) ||
(ENTRY_VAL(old, NPF_WORKSTATIONS) &&
- pdb_get_workstations(sampass)) &&
+ (pdb_get_workstations(sampass)) &&
strcmp( ENTRY_VAL(old, NPF_WORKSTATIONS),
- pdb_get_workstations(sampass))) {
+ pdb_get_workstations(sampass)))) {
need_to_modify = True;
set_single_attribute(obj, NPF_WORKSTATIONS,
pdb_get_workstations(sampass),
@@ -899,7 +1427,7 @@ static BOOL init_nisp_from_sam(nis_object *obj, const SAM_ACCOUNT *sampass,
/***************************************************************
calls nis_list, returns results.
****************************************************************/
-static nis_result *nisp_get_nis_list(const char *nis_name, unsigned int flags)
+static nis_result *nisp_get_nis_list(const char *nisname, unsigned int flags)
{
nis_result *result;
int i;
@@ -909,17 +1437,11 @@ static nis_result *nisp_get_nis_list(const char *nis_name, unsigned int flags)
for(i = 0; i<2;i++ ) {
alarm(60); /* hopefully ok for long searches */
- result = nis_list(nis_name, flags,NULL,NULL);
+ result = nis_list(nisname, flags,NULL,NULL);
alarm(0);
CatchSignal(SIGALRM, SIGNAL_CAST SIG_DFL);
- if (gotalarm)
- {
- DEBUG(0,("NIS+ lookup time out\n"));
- nis_freeresult(result);
- return NULL;
- }
if( !(flags & MASTER_ONLY) && NIS_RES_NUMOBJ(result) <= 0 ) {
/* nis replicas are not in sync perhaps?
* this can happen, if account was just added.
@@ -933,506 +1455,10 @@ static nis_result *nisp_get_nis_list(const char *nis_name, unsigned int flags)
return result;
}
-/***************************************************************
- Start to enumerate the nisplus passwd list.
- ****************************************************************/
-BOOL pdb_setsampwent(BOOL update)
-{
- char *sp, * p = lp_smb_passwd_file();
- pstring pfiletmp;
-
- if( (sp = strrchr( p, '/' )) )
- safe_strcpy(pfiletmp, sp+1, sizeof(pfiletmp)-1);
- else
- safe_strcpy(pfiletmp, p, sizeof(pfiletmp)-1);
- safe_strcat(pfiletmp, ".org_dir", sizeof(pfiletmp)-strlen(pfiletmp)-1);
-
- pdb_endsampwent(); /* just in case */
- global_nisp_ent.result = nisp_get_nis_list( pfiletmp, 0 );
- global_nisp_ent.enum_entry = 0;
- return global_nisp_ent.result != NULL ? True : False;
-}
-
-/***************************************************************
- End enumeration of the nisplus passwd list.
-****************************************************************/
-void pdb_endsampwent(void)
-{
- if( global_nisp_ent.result )
- nis_freeresult(global_nisp_ent.result);
- global_nisp_ent.result = NULL;
- global_nisp_ent.enum_entry = 0;
-}
-
-/*************************************************************************
- Routine to return the next entry in the nisplus passwd list.
- *************************************************************************/
-BOOL pdb_getsampwent(SAM_ACCOUNT *user)
-{
- int enum_entry = (int)(global_nisp_ent.enum_entry);
- nis_result *result = global_nisp_ent.result;
-
- if (user==NULL) {
- DEBUG(0,("SAM_ACCOUNT is NULL.\n"));
- return False;
- }
-
- if (result == NULL ||
- enum_entry < 0 || enum_entry >= (NIS_RES_NUMOBJ(result) - 1))
- {
- return False;
- }
-
- if(!make_sam_from_nisp_object(user, &NIS_RES_OBJECT(result)[enum_entry]) )
- {
- DEBUG(0,("Bad SAM_ACCOUNT entry returned from NIS+!\n"));
- return False;
- }
- (int)(global_nisp_ent.enum_entry)++;
- return True;
-}
-
-/*************************************************************************
- Routine to search the nisplus passwd file for an entry matching the username
- *************************************************************************/
-BOOL pdb_getsampwnam(SAM_ACCOUNT * user, const char *sname)
-{
- /* Static buffers we will return. */
- nis_result *result = NULL;
- pstring nisname;
- BOOL ret;
- char *pfile = lp_smb_passwd_file();
- int i;
-
- if (!*pfile)
- {
- DEBUG(0, ("No SMB password file set\n"));
- return False;
- }
- if( strrchr( pfile, '/') )
- pfile = strrchr( pfile, '/') + 1;
-
- slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.org_dir", sname, pfile);
- DEBUG(10, ("search by nisname: %s\n", nisname));
-
- /* Search the table. */
-
- if(!(result = nisp_get_nis_list(nisname, 0)))
- {
- return False;
- }
-
- ret = make_sam_from_nisresult(user, result);
- nis_freeresult(result);
-
- return ret;
-}
-
-/*************************************************************************
- Routine to search the nisplus passwd file for an entry matching the username
- *************************************************************************/
-
-BOOL pdb_getsampwsid(SAM_ACCOUNT * user, const DOM_SID *sid)
-{
- uint32 rid;
- if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
- return False;
- return pdb_getsampwrid(user, rid);
-}
-
-static BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid)
-{
- nis_result *result;
- char *nisname;
- BOOL ret;
- char *sp, *p = lp_smb_passwd_file();
- pstring pfiletmp;
-
- if (!*p)
- {
- DEBUG(0, ("no SMB password file set\n"));
- return False;
- }
-
- if( (sp = strrchr( p, '/' )) )
- safe_strcpy(pfiletmp, sp+1, sizeof(pfiletmp)-1);
- else
- safe_strcpy(pfiletmp, p, sizeof(pfiletmp)-1);
- safe_strcat(pfiletmp, ".org_dir", sizeof(pfiletmp)-strlen(pfiletmp)-1);
-
- nisname = make_nisname_from_user_rid(rid, pfiletmp);
-
- DEBUG(10, ("search by rid: %s\n", nisname));
-
- /* Search the table. */
-
- if(!(result = nisp_get_nis_list(nisname, 0)))
- {
- return False;
- }
-
- ret = make_sam_from_nisresult(user, result);
- nis_freeresult(result);
-
- return ret;
-}
-
-/*************************************************************************
- Routine to remove entry from the nisplus smbpasswd table
- *************************************************************************/
-BOOL pdb_delete_sam_account(SAM_ACCOUNT * user)
-{
- const char *sname;
- char *pfile = lp_smb_passwd_file();
- pstring nisname;
- nis_result *result, *delresult;
- nis_object *obj;
- int i;
-
- if (!user) {
- DEBUG(0, ("no SAM_ACCOUNT specified!\n"));
- return False;
- }
-
- sname = pdb_get_username(user);
-
- if (!*pfile)
- {
- DEBUG(0, ("no SMB password file set\n"));
- return False;
- }
- if( strrchr( pfile, '/') )
- pfile = strrchr( pfile, '/') + 1;
-
- slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.org_dir", sname, pfile);
-
- /* Search the table. */
-
- if( !(result = nisp_get_nis_list(nisname,
- MASTER_ONLY|FOLLOW_LINKS|FOLLOW_PATH|\
- EXPAND_NAME|HARD_LOOKUP))) {
- return False;
- }
-
- if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) {
- /* User not found. */
- DEBUG(0,("user not found in NIS+\n"));
- nis_freeresult(result);
- return False;
- }
-
- obj = NIS_RES_OBJECT(result);
- slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.%s", sname, obj->zo_name,
- obj->zo_domain);
-
- DEBUG(10, ("removing name: %s\n", nisname));
- delresult = nis_remove_entry(nisname, obj,
- MASTER_ONLY|REM_MULTIPLE|ALL_RESULTS|FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
-
- nis_freeresult(result);
-
- if(delresult->status != NIS_SUCCESS) {
- DEBUG(0, ("NIS+ table update failed: %s %s\n",
- nisname, nis_sperrno(delresult->status)));
- nis_freeresult(delresult);
- return False;
- }
- nis_freeresult(delresult);
- return True;
-}
-
-/************************************************************************
- Routine to add an entry to the nisplus passwd file.
-*************************************************************************/
-BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd)
-{
- int local_user = 0;
- char *pfile;
- pstring pfiletmp;
- char *nisname;
- nis_result *result = NULL,
- *tblresult = NULL;
- nis_object new_obj;
- entry_col *ecol;
- int ta_maxcol;
-
- /*
- * 1. find user domain.
- * a. try nis search in passwd.org_dir - if found use domain from result.
- * b. try getpwnam. this may be needed if user is defined
- * in /etc/passwd file (or elsewere) and not in passwd.org_dir.
- * if found, use host default domain.
- * c. exit with False - no such user.
- *
- * 2. add user
- * a. find smbpasswd table
- * search pfile in user domain if not found, try host default
- * domain.
- * b. smbpasswd domain is found, fill data and add entry.
- *
- * pfile should contain ONLY table name, org_dir will be concated.
- * so, at first we will clear path prefix from pfile, and
- * then we will use pfiletmp as playground to put together full
- * nisname string.
- * such approach will make it possible to specify samba private dir
- * AND still use NIS+ table. as all domain related data is normally
- * stored in org_dir.DOMAIN, this should be ok do do.
- */
-
- pfile = lp_smb_passwd_file();
- if( strrchr( pfile, '/') )
- pfile = strrchr( pfile, '/') + 1;
-
- /*
- * Check if user is already there.
- */
- safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
- safe_strcat(pfiletmp, ".org_dir",
- sizeof(pfiletmp)-strlen(pfiletmp)-1);
-
- if(pdb_get_username(newpwd) != NULL) {
- nisname = make_nisname_from_name(pdb_get_username(newpwd),
- pfiletmp);
- } else {
- return False;
- }
-
- if(!(result = nisp_get_nis_list(nisname, MASTER_ONLY|FOLLOW_LINKS|\
- FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP))) {
- return False;
- }
- if (result->status != NIS_SUCCESS &&
- result->status != NIS_NOTFOUND) {
- DEBUG(3, ( "nis_list failure: %s: %s\n",
- nisname, nis_sperrno(result->status)));
- nis_freeresult(result);
- return False;
- }
-
- if (result->status == NIS_SUCCESS && NIS_RES_NUMOBJ(result) > 0)
- {
- DEBUG(3, ("User already exists in NIS+ password db: %s\n",
- pfile));
- nis_freeresult(result);
- return False;
- }
-
- nis_freeresult(result); /* no such user, free results */
-
- /*
- * check for user in unix password database. we need this to get
- * domain, where smbpasswd entry should be stored.
- */
-
- nisname = make_nisname_from_name(pdb_get_username(newpwd),
- "passwd.org_dir");
-
- result = nisp_get_nis_list(nisname,
- MASTER_ONLY|FOLLOW_LINKS|FOLLOW_PATH|\
- EXPAND_NAME|HARD_LOOKUP);
-
- if (result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0)
- {
- struct passwd *passwd;
- DEBUG(3, ("nis_list failure: %s: %s\n",
- nisname, nis_sperrno(result->status)));
- nis_freeresult(result);
-
- if (!(passwd = getpwnam_alloc(pdb_get_username(newpwd)))) {
- /* no such user in system! */
- return False;
- }
- passwd_free(&passwd);
-
- /*
- * user is defined, but not in passwd.org_dir.
- */
- local_user = 1;
- } else {
- safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
- safe_strcat(pfiletmp, ".", sizeof(pfiletmp)-strlen(pfiletmp)-1);
- safe_strcat(pfiletmp, NIS_RES_OBJECT(result)->zo_domain,
- sizeof(pfiletmp)-strlen(pfiletmp)-1);
- nis_freeresult(result); /* not needed any more */
-
- tblresult = nisp_get_nis_list(pfiletmp,
- MASTER_ONLY|FOLLOW_LINKS|\
- FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
- }
-
- if (local_user || tblresult->status != NIS_SUCCESS)
- {
- /*
- * no user domain or
- * smbpasswd table not found in user domain, fallback to
- * default domain.
- */
- if (!local_user) /* free previous failed search result */
- nis_freeresult(tblresult);
-
- safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
- safe_strcat(pfiletmp, ".org_dir",
- sizeof(pfiletmp)-strlen(pfiletmp)-1);
- tblresult = nis_lookup(pfiletmp, MASTER_ONLY|FOLLOW_LINKS|\
- FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
- if (tblresult->status != NIS_SUCCESS)
- {
- /* still nothing. bail out */
- nis_freeresult(tblresult);
- DEBUG(3, ( "nis_lookup failure: %s\n",
- nis_sperrno(tblresult->status)));
- return False;
- }
- /* we need full name for nis_add_entry() */
- safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
- safe_strcat(pfiletmp, ".", sizeof(pfiletmp)-strlen(pfiletmp)-1);
- safe_strcat(pfiletmp, NIS_RES_OBJECT(tblresult)->zo_domain,
- sizeof(pfiletmp)-strlen(pfiletmp)-1);
- }
-
- memset((char *)&new_obj, 0, sizeof (new_obj));
- /* fill entry headers */
- /* we do not free these. */
- new_obj.zo_name = NIS_RES_OBJECT(tblresult)->zo_name;
- new_obj.zo_owner = NIS_RES_OBJECT(tblresult)->zo_owner;
- new_obj.zo_group = NIS_RES_OBJECT(tblresult)->zo_group;
- new_obj.zo_domain = NIS_RES_OBJECT(tblresult)->zo_domain;
- /* uints */
- new_obj.zo_access = NIS_RES_OBJECT(tblresult)->zo_access;
- new_obj.zo_ttl = NIS_RES_OBJECT(tblresult)->zo_ttl;
-
- new_obj.zo_data.zo_type = ENTRY_OBJ;
- new_obj.EN_data.en_type =
- NIS_RES_OBJECT(tblresult)->TA_data.ta_type;
-
- ta_maxcol = NIS_RES_OBJECT(tblresult)->TA_data.ta_maxcol;
-
- if(!(ecol = (entry_col*)malloc(ta_maxcol*sizeof(entry_col)))) {
- DEBUG(0, ("memory allocation failure\n"));
- nis_freeresult(tblresult);
- return False;
- }
-
- memset((char *)ecol, 0, ta_maxcol*sizeof (entry_col));
- new_obj.EN_data.en_cols.en_cols_val = ecol;
- new_obj.EN_data.en_cols.en_cols_len = ta_maxcol;
-
- init_nisp_from_sam(&new_obj, newpwd, NULL);
-
- DEBUG(10, ( "add NIS+ entry: %s\n", nisname));
- result = nis_add_entry(pfiletmp, &new_obj, 0);
-
- free(ecol); /* free allocated entry space */
-
- if (result->status != NIS_SUCCESS)
- {
- DEBUG(3, ( "NIS+ table update failed: %s\n",
- nisname, nis_sperrno(result->status)));
- nis_freeresult(tblresult);
- nis_freeresult(result);
- return False;
- }
-
- nis_freeresult(tblresult);
- nis_freeresult(result);
-
- return True;
-}
-
-/************************************************************************
- Routine to modify the nisplus passwd entry.
-************************************************************************/
-BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd)
-{
- nis_result *result, *addresult;
- nis_object *obj;
- nis_object new_obj;
- entry_col *ecol;
- int ta_maxcol;
- char *pfile = lp_smb_passwd_file();
- pstring nisname;
- int i;
-
- if (!*pfile)
- {
- DEBUG(0, ("no SMB password file set\n"));
- return False;
- }
- if( strrchr( pfile, '/') )
- pfile = strrchr( pfile, '/') + 1;
-
- slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.org_dir",
- pdb_get_username(newpwd), pfile);
-
- DEBUG(10, ("search by name: %s\n", nisname));
-
- /* Search the table. */
-
- if( !(result = nisp_get_nis_list(nisname, MASTER_ONLY|FOLLOW_LINKS|\
- FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP))) {
- return False;
- }
-
- if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) {
- /* User not found. */
- DEBUG(0,("user not found in NIS+\n"));
- nis_freeresult(result);
- return False;
- }
-
- obj = NIS_RES_OBJECT(result);
- DEBUG(6,("entry found in %s\n", obj->zo_domain));
-
- /* we must create new stub object with EN_MODIFIED flag.
- this is because obj from result is going to be freed and
- we do not want to break it or cause memory leaks or corruption.
- */
-
- memmove((char *)&new_obj, obj, sizeof (new_obj));
- ta_maxcol = obj->TA_data.ta_maxcol;
-
- if(!(ecol = (entry_col*)malloc(ta_maxcol*sizeof(entry_col)))) {
- DEBUG(0, ("memory allocation failure\n"));
- nis_freeresult(result);
- return False;
- }
-
- memmove((char *)ecol, obj->EN_data.en_cols.en_cols_val,
- ta_maxcol*sizeof (entry_col));
- new_obj.EN_data.en_cols.en_cols_val = ecol;
- new_obj.EN_data.en_cols.en_cols_len = ta_maxcol;
-
- if ( init_nisp_from_sam(&new_obj, newpwd, obj) == True ) {
- slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.%s",
- pdb_get_username(newpwd), pfile, obj->zo_domain);
-
- DEBUG(10, ("NIS+ table update: %s\n", nisname));
- addresult =
- nis_modify_entry(nisname, &new_obj,
- MOD_SAMEOBJ | FOLLOW_PATH | EXPAND_NAME | HARD_LOOKUP);
-
- if(addresult->status != NIS_SUCCESS) {
- DEBUG(0, ("NIS+ table update failed: %s %s\n",
- nisname, nis_sperrno(addresult->status)));
- nis_freeresult(addresult);
- nis_freeresult(result);
- free(ecol);
- return False;
- }
-
- DEBUG(6,("password changed\n"));
- nis_freeresult(addresult);
- } else {
- DEBUG(6,("nothing to change!\n"));
- }
-
- free(ecol);
- nis_freeresult(result);
-
- return True;
+#else
+NTSTATUS pdb_init_nisplussam(PDB_CONTEXT *c, PDB_METHODS **m, const char *l)
+{
+ DEBUG(0, ("nisplus sam not compiled in!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
}
-
-#else
- void nisplus_dummy_function(void);
- void nisplus_dummy_function(void) { } /* stop some compilers complaining */
-#endif /* WITH_NISPLUSSAM */
+#endif /* WITH_NISPLUS_SAM */