Text-base idmap backend module for samba 3.0.2a

Ikebe Takashi iktaka99 at hotmail.com
Fri Apr 9 02:24:32 GMT 2004


Hi,
I made patch of text-base idmap backend module including configure, 
Makefile.in and other staffs.
I also make them into patch file for samba 3.0.2a.
Text-base idmap backend module can provide you "ldap-free" flexible 
SID-to-UID mapping.
When you want to run this module, please specify "idmap backend = text" in 
your smb.conf.
"idmap uid" & "idmap gid" on smb.conf are used for the user that is not 
writen on text backend.
text backend is writen in smbidmap file which locate on your "CONFIGDIR"(on 
my Fedora env this is /etc/samba) as below;

SID UID/GID TYPE(1=user/2=group)

Even if you do not set your smbidmap at first time, this module 
automatically dump new mapping to smbidmap file.
After dump, stop winbind and edit smbidmap as you want.
After edit, please delete cache file which locate on /var/lib/samba/*.tdb.
You can make completley same id mapping on multiple samba server without 
ldap, and this is very convinient for NIS interoperability.

Thank you.
Takashi Ikebe
e-mail : iktaka99 at hotmail.com

_________________________________________________________________
友達と24時間ホットライン「MSN メッセンジャー」、今すぐダウンロード!  
http://messenger.msn.co.jp 
-------------- next part --------------
diff -urpbBP samba-3.0.2a/source/Makefile.in 
samba-3.0.2a-text/source/Makefile.in
--- samba-3.0.2a/source/Makefile.in	2004-02-14 00:12:52.000000000 +0900
+++ samba-3.0.2a-text/source/Makefile.in	2004-04-09 10:57:02.664577024 +0900
@@ -79,6 +79,7 @@ INSTALLPERMS = 0755
LOGFILEBASE = @logfilebase@
CONFIGFILE = $(CONFIGDIR)/smb.conf
LMHOSTSFILE = $(CONFIGDIR)/lmhosts
+IDMAP_TEXT_FILE = $(CONFIGDIR)/smbidmap

# This is where smbpasswd et al go
PRIVATEDIR = @privatedir@
@@ -116,7 +117,7 @@ PATH_FLAGS3 = $(PATH_FLAGS2) -DLMHOSTSFI
PATH_FLAGS4 = $(PATH_FLAGS3) -DSWATDIR=\"$(SWATDIR)\"  
-DLOCKDIR=\"$(LOCKDIR)\" -DPIDDIR=\"$(PIDDIR)\"
PATH_FLAGS5 = $(PATH_FLAGS4) -DLIBDIR=\"$(LIBDIR)\" \
	      -DLOGFILEBASE=\"$(LOGFILEBASE)\" -DSHLIBEXT=\"@SHLIBEXT@\"
-PATH_FLAGS6 = $(PATH_FLAGS5) -DCONFIGDIR=\"$(CONFIGDIR)\"
+PATH_FLAGS6 = $(PATH_FLAGS5) -DCONFIGDIR=\"$(CONFIGDIR)\" 
-DIDMAP_TEXT_FILE=\"$(IDMAP_TEXT_FILE)\"
PATH_FLAGS = $(PATH_FLAGS6) $(PASSWD_FLAGS)

# Note that all executable programs now provide for an optional executable 
suffix.
diff -urpbBP samba-3.0.2a/source/configure 
samba-3.0.2a-text/source/configure
--- samba-3.0.2a/source/configure	2004-02-14 00:12:52.000000000 +0900
+++ samba-3.0.2a-text/source/configure	2004-04-09 09:50:02.488736648 +0900
@@ -23367,7 +23367,7 @@ cat >>confdefs.h <<\_ACEOF
#define HAVE_LDAP 1
_ACEOF

-    default_static_modules="$default_static_modules pdb_ldap idmap_ldap";
+    default_static_modules="$default_static_modules pdb_ldap idmap_ldap 
idmap_text";
     SMBLDAP="lib/smbldap.o"
     with_ldap_support=yes
     echo "$as_me:$LINENO: checking whether LDAP support is used" >&5
@@ -31937,6 +31937,41 @@ _ACEOF
     	rm -f smbd/server.o


+	echo "$as_me:$LINENO: checking how to build idmap_text" >&5
+echo $ECHO_N "checking how to build idmap_text... $ECHO_C" >&6
+	if test "$MODULE_idmap_text"; then
+		DEST=$MODULE_idmap_text
+	elif test "$MODULE_idmap" -a "$MODULE_DEFAULT_idmap_text"; then
+		DEST=$MODULE_idmap
+	else
+		DEST=$MODULE_DEFAULT_idmap_text
+	fi
+
+	if test x"$DEST" = xSHARED; then
+
+cat >>confdefs.h <<\_ACEOF
+#define idmap_text_init init_module
+_ACEOF
+
+		IDMAP_MODULES="$IDMAP_MODULES "bin/idmap_text.$SHLIBEXT""
+		echo "$as_me:$LINENO: result: shared" >&5
+echo "${ECHO_T}shared" >&6
+
+		string_shared_modules="$string_shared_modules idmap_text"
+	elif test x"$DEST" = xSTATIC; then
+		init_static_modules_idmap="$init_static_modules_idmap idmap_text_init();"
+		string_static_modules="$string_static_modules idmap_text"
+		IDMAP_STATIC="$IDMAP_STATIC sam/idmap_text.o"
+
+
+		echo "$as_me:$LINENO: result: static" >&5
+echo "${ECHO_T}static" >&6
+	else
+	    string_ignored_modules="$string_ignored_modules idmap_text"
+		echo "$as_me:$LINENO: result: not" >&5
+echo "${ECHO_T}not" >&6
+	fi
+

	echo "$as_me:$LINENO: checking how to build idmap_ldap" >&5
echo $ECHO_N "checking how to build idmap_ldap... $ECHO_C" >&6
diff -urpbBP samba-3.0.2a/source/dynconfig.c 
samba-3.0.2a-text/source/dynconfig.c
--- samba-3.0.2a/source/dynconfig.c	2004-02-14 00:12:52.000000000 +0900
+++ samba-3.0.2a-text/source/dynconfig.c	2004-04-09 10:56:23.191577832 +0900
@@ -46,6 +46,8 @@ char const *dyn_SBINDIR = SBINDIR,

pstring dyn_CONFIGFILE = CONFIGFILE; /**< Location of smb.conf file. **/

+pstring dyn_IDMAP_TEXT_FILE = IDMAP_TEXT_FILE; /**< Location of smbidmap 
file. **/
+
/** Log file directory. **/
pstring dyn_LOGFILEBASE = LOGFILEBASE;

diff -urpbBP samba-3.0.2a/source/include/config.h.in 
samba-3.0.2a-text/source/include/config.h.in
--- samba-3.0.2a/source/include/config.h.in	2004-02-14 00:12:44.000000000 
+0900
+++ samba-3.0.2a-text/source/include/config.h.in	2004-04-09 
09:50:11.777324568 +0900
@@ -1836,6 +1836,9 @@
/* Define to `int' if <sys/types.h> doesn't define. */
#undef gid_t

+/* Whether to build idmap_text as shared module */
+#undef idmap_text_init
+
/* Whether to build idmap_ldap as shared module */
#undef idmap_ldap_init

diff -urpbBP samba-3.0.2a/source/include/dynconfig.h 
samba-3.0.2a-text/source/include/dynconfig.h
--- samba-3.0.2a/source/include/dynconfig.h	2004-02-14 00:12:43.000000000 
+0900
+++ samba-3.0.2a-text/source/include/dynconfig.h	2004-04-09 
10:56:44.055406048 +0900
@@ -31,6 +31,7 @@ extern char const *dyn_SBINDIR,
extern pstring dyn_CONFIGFILE;
extern pstring dyn_LOGFILEBASE, dyn_LMHOSTSFILE;
extern pstring dyn_LIBDIR;
+extern pstring dyn_IDMAP_TEXT_FILE;
extern const fstring dyn_SHLIBEXT;
extern const pstring dyn_LOCKDIR;
extern const pstring dyn_PIDDIR;
diff -urpbBP samba-3.0.2a/source/sam/idmap_text.c 
samba-3.0.2a-text/source/sam/idmap_text.c
--- samba-3.0.2a/source/sam/idmap_text.c	1970-01-01 09:00:00.000000000 +0900
+++ samba-3.0.2a-text/source/sam/idmap_text.c	2004-04-09 10:57:17.392338064 
+0900
@@ -0,0 +1,322 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   idmap TEXT backend
+
+   Copyright (C) Takashi Ikebe <iktaka99 at hotmail.com>
+
+   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"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_IDMAP
+
+#define MAXLINE 255
+
+struct sid2uid{
+  fstring sid;
+  int   id;
+  int   type;
+  struct sid2uid *nextptr;
+};
+
+struct sid2uid *newptr, *currentptr, *previousptr;
+
+FILE *fpr;
+
+/* default uid/gid to use unknown SID mapping */
+int startuid;
+int startgid;
+
+/*****************************************************************************
+ Open mapping file and import as list.
+*****************************************************************************/
+
+static NTSTATUS text_idmap_init( char *params )
+{
+  DEBUG(3,("idmap_text_root running\ntext_idmap_init start\n"));
+  fpr = fopen(dyn_IDMAP_TEXT_FILE, "r+");
+  if(fpr==NULL){
+  fpr = fopen(dyn_IDMAP_TEXT_FILE, "w+");
+  }
+  currentptr=NULL;
+  previousptr=NULL;
+  char tmpc[MAXLINE];
+  int i, j,tmuid,tmgid;
+  uid_t luid, huid;
+  gid_t lgid, hgid;
+  if( !lp_idmap_uid(&luid, &huid) || !lp_idmap_gid(&lgid, &hgid)){
+    DEBUG(3,("text_idmap_init: idmap uid/gid parameters wrong\n"));
+    return NT_STATUS_UNSUCCESSFUL;
+  }
+  tmuid=(int)luid;
+  tmgid=(int)lgid;
+  memset(tmpc,0,MAXLINE);
+  while(fgets(tmpc,MAXLINE,fpr)){
+    if(tmpc[0]!='#'){
+      newptr=malloc(sizeof(struct sid2uid));
+      if(newptr!=NULL){
+        sscanf(tmpc,"%s %d %d",newptr->sid,&newptr->id,&newptr->type);
+        DEBUG(3,("sid=%s, id=%d, 
type=%d\n",newptr->sid,newptr->id,newptr->type));
+        if(previousptr==NULL){
+          previousptr=newptr;
+          previousptr->nextptr=NULL;
+        }else{
+          currentptr=previousptr;
+          while(currentptr->nextptr!=NULL){
+            currentptr=currentptr->nextptr;
+          }
+          currentptr->nextptr=newptr;
+        }
+        memset(tmpc,0,MAXLINE+1);
+        //also need to add maximum uid search
+        if(newptr->type==1){
+          if(tmuid <= newptr->id){
+            tmuid=newptr->id + 1;
+          }
+        }else if(newptr->type==2){
+          if(tmgid <= newptr->id){
+            tmgid=newptr->id + 1;
+          }
+        }
+      }else{
+        /*malloc error OOM*/
+        DEBUG(3,("nomemory\n"));
+        return NT_STATUS_NO_MEMORY;
+      }
+    }
+  }
+  startuid=tmuid;
+  startgid=tmgid;
+  DEBUG(3,("text_idmap_init stop\n"));
+  return NT_STATUS_OK;
+}
+
+/*****************************************************************************
+ Allocate a new RID
+*****************************************************************************/
+
+static NTSTATUS text_allocate_rid(uint32 *rid, int rid_type)
+{
+  /*
+    I don't think this function is essential on text mapping.
+    Anyone want to use RID on text base backend mapping?.
+    it seems too complex for text base mapping...
+  */
+  DEBUG(3,("allocate_rid\n"));
+  return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/*****************************************************************************
+ Allocate a new uid or gid
+*****************************************************************************/
+
+static NTSTATUS text_allocate_id(unid_t *id, int id_type)
+{
+  /*
+    I don't think this function is essential on text mapping.
+    User just add mapping to text file.
+    I will implement this future.
+  */
+  DEBUG(3,("allocate_id\n"));
+  return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+
+/*****************************************************************************
+ Internal function:Allocate a new uid or gid to unknown SID
+ and write back to mapfile
+*****************************************************************************/
+
+static int text_add_id_from_sid(DOM_SID *sid, int *id_type)
+{
+  DEBUG(3,("add_id_from_sid start\n"));
+  fstring keystr;
+  char tmpc[MAXLINE];
+  int i,ret;
+  ret=0;
+  sid_to_string(keystr,sid);
+  DEBUG(3,("keystr at add_id=%s\n",keystr));
+  //add list
+  newptr=malloc(sizeof(struct sid2uid));
+  if(newptr != NULL){
+    i=0;
+    while(keystr[i]!=' ' && keystr[i]!='\n'){
+      i++;
+    }
+    strncpy(newptr->sid,keystr,i);
+    if(*id_type==ID_USERID){
+      newptr->id=startuid;
+      startuid++;
+    }else if(*id_type==ID_GROUPID){
+      newptr->id=startgid;
+      startgid++;
+    }else{
+      //unknown type;
+      return 0;
+    }
+    ret = newptr->id;
+    newptr->type=*id_type;
+    newptr->nextptr=NULL;
+    if(previousptr==NULL){
+      previousptr=newptr;
+      previousptr->nextptr=NULL;
+    }else{
+      currentptr=previousptr;
+      while(currentptr->nextptr!=NULL){
+        currentptr=currentptr->nextptr;
+      }
+      currentptr->nextptr=newptr;
+    }
+
+    
DEBUG(3,("text_add_id:sid=%s,id=%d,type=%d\n",newptr->sid,newptr->id,newptr->type));
+    //writeback to file;
+    if(fprintf(fpr,"%s %d %d\n",newptr->sid,newptr->id,newptr->type)<0){
+      DEBUG(3,("error! can't write back!"));
+    }else{
+      DEBUG(3,("write back!"));
+    }
+    DEBUG(3,(" ret=%d\n",newptr->id));
+  }else{
+    //error by OOM
+    DEBUG(3,("Memory Error!\n"));
+    return 0;
+  }
+
+  DEBUG(3,("add_id_from_sid stop ret=%d\n",newptr->id));
+  return ret;
+}
+
+
+/*****************************************************************************
+ Get sid from id(uid/gid)
+*****************************************************************************/
+
+static NTSTATUS text_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
+{
+  DEBUG(3,("get_sid_from_id start\n"));
+  fstring keystr,tempstr;
+  currentptr=previousptr;
+  string_to_sid(sid,currentptr->sid);
+  while(currentptr!=NULL){
+    if(currentptr->type==id_type){
+      if(id_type==ID_USERID && currentptr->id==id.uid){
+        DEBUG(3,("get_sid_from_id stop\n"));
+        return NT_STATUS_OK;
+      }else if(id_type==ID_GROUPID && currentptr->id==id.gid){
+        string_to_sid(sid,currentptr->sid);
+        DEBUG(3,("get_sid_from_id stop\n"));
+        return NT_STATUS_OK;
+      }
+    }
+    currentptr=currentptr->nextptr;
+  }
+  DEBUG(3,("get_sid_from_id fail\n"));
+  return NT_STATUS_UNSUCCESSFUL;
+}
+
+/*****************************************************************************
+ Get id(uid/gid) from sid
+*****************************************************************************/
+
+static NTSTATUS text_get_id_from_sid(unid_t *id, int *id_type, const 
DOM_SID *sid)
+{
+  DEBUG(3,("get_id_from_sid start\n"));
+  int tmpid;
+  fstring keystr,tempstr;
+  currentptr=previousptr;
+  memset(keystr,0,FSTRING_LEN);
+  sid_to_string(keystr,sid);
+  DEBUG(3,("keystring=%s, id_type=%d\n",keystr, *id_type));
+  while(currentptr!=NULL){
+    if(strncmp(keystr,currentptr->sid,FSTRING_LEN)==0){
+      if(*id_type == ID_USERID){
+        id->uid=currentptr->id;
+      }else if(*id_type == ID_GROUPID){
+        id->gid=currentptr->id;
+      }
+      DEBUG(3,("get_id_from_sid stop\n"));
+      return NT_STATUS_OK;
+    }
+    currentptr=currentptr->nextptr;
+  }
+  DEBUG(3,("get_id_from_sid fail\n"));
+  DEBUG(3,("keystr at id_from_sid=%s\n",keystr));
+  if(strncmp(keystr,"(NULL SID)",10)){
+    tmpid=text_add_id_from_sid(sid, id_type);
+    if(tmpid){
+      if(*id_type==ID_USERID){
+        id->uid=tmpid;
+      }else if(*id_type==ID_GROUPID){
+        id->gid=tmpid;
+      }else{
+        DEBUG(3,("Unknown ID\n"));
+        return NT_STATUS_UNSUCCESSFUL;
+      }
+      DEBUG(3,("get_id_from_sid stop, id=%d, type=%d\n",tmpid, *id_type));
+      return NT_STATUS_OK;
+    }
+  }else{
+    DEBUG(3,("NULL SID\n"));
+    return NT_STATUS_UNSUCCESSFUL;
+  }
+}
+
+
+static NTSTATUS text_set_mapping(const DOM_SID *sid, unid_t id, int 
id_type)
+{
+  DEBUG(3,("set_mapping\n"));
+  return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+
+static NTSTATUS text_idmap_close(void)
+{
+  if(fpr!=NULL){
+    fclose(fpr);
+  }
+  DEBUG(3,("idmap_close\n"));
+  while(previousptr!=NULL){
+    newptr=previousptr;
+    previousptr=previousptr->nextptr;
+    SAFE_FREE(newptr);
+  }
+  DEBUG(3,("memory freed\n"));
+  return NT_STATUS_OK;
+}
+
+static void text_idmap_status(void)
+{
+  DEBUG(3,("idmap text status not available\n"));
+}
+
+static struct idmap_methods text_methods = {
+  text_idmap_init,
+  text_allocate_rid,
+  text_allocate_id,
+  text_get_sid_from_id,
+  text_get_id_from_sid,
+  text_set_mapping,
+  text_idmap_close,
+  text_idmap_status
+
+};
+
+NTSTATUS idmap_text_init(void)
+{
+  return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "text", 
&text_methods);
+}



More information about the samba-technical mailing list