s4-param Add hook between Samba3 and Samba4 loadparm systems.
authorAndrew Bartlett <abartlet@samba.org>
Wed, 1 Jun 2011 13:22:24 +0000 (23:22 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Mon, 6 Jun 2011 07:37:51 +0000 (17:37 +1000)
In the top level build, this allows calls to code that requires a
lpcfg_ style loadparm_context, while using the global parameters
loaded from the source3 loadparm code.

Andrew Bartlett

source3/include/proto.h
source3/param/loadparm.c
source3/param/loadparm_ctx.c [new file with mode: 0644]
source3/wscript_build
source4/param/loadparm.c
source4/param/param.h
source4/param/wscript_build
source4/script/mks3param.pl [new file with mode: 0644]

index c6fd38dd81571603f30a3edc3334531dab7121c2..f732a536550df12ae8550f14bdf6a7bf52a7d15c 100644 (file)
@@ -1210,6 +1210,7 @@ char *lp_passwd_chat(void);
 const char *lp_passwordserver(void);
 const char *lp_name_resolve_order(void);
 const char *lp_realm(void);
+const char *lp_dnsdomain(void);
 const char *lp_afs_username_map(void);
 int lp_afs_token_lifetime(void);
 char *lp_log_nt_token_command(void);
@@ -1662,6 +1663,10 @@ void lp_set_passdb_backend(const char *backend);
 void widelinks_warning(int snum);
 const char *lp_ncalrpc_dir(void);
 
+/* The following definitions come from param/loadparm_ctx.c  */
+
+const struct loadparm_s3_context *loadparm_s3_context(void);
+
 /* The following definitions come from param/loadparm_server_role.c  */
 
 int lp_server_role(void);
index 350c95d9acf8948fddd346749f5f120287d3d34a..dc79c36f1991ccfe668d0ab8c4e831f82b607e70 100644 (file)
@@ -159,6 +159,8 @@ struct global {
        char *szPasswordServer;
        char *szSocketOptions;
        char *szRealm;
+       char *szRealmUpper;
+       char *szDnsDomain;
        char *szAfsUsernameMap;
        int iAfsTokenLifetime;
        char *szLogNtTokenCommand;
@@ -705,6 +707,7 @@ static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
+static bool handle_realm( int snum, const char *pszParmValue, char **ptr );
 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
@@ -1019,7 +1022,7 @@ static struct parm_struct parm_table[] = {
                .type           = P_USTRING,
                .p_class        = P_GLOBAL,
                .ptr            = &Globals.szRealm,
-               .special        = NULL,
+               .special        = handle_realm,
                .enum_list      = NULL,
                .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
        },
@@ -5616,7 +5619,8 @@ FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
 FN_GLOBAL_CONST_STRING(lp_passwordserver, &Globals.szPasswordServer)
 FN_GLOBAL_CONST_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
-FN_GLOBAL_CONST_STRING(lp_realm, &Globals.szRealm)
+FN_GLOBAL_CONST_STRING(lp_realm, &Globals.szRealmUpper)
+FN_GLOBAL_CONST_STRING(lp_dnsdomain, &Globals.szDnsDomain)
 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
@@ -7593,6 +7597,21 @@ static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
        return ret;
 }
 
+static bool handle_realm(int snum, const char *pszParmValue, char **ptr)
+{
+       bool ret = true;
+       char *realm = strupper_talloc(talloc_tos(), pszParmValue);
+       char *dnsdomain = strlower_talloc(talloc_tos(), pszParmValue);
+
+       ret &= string_set(&Globals.szRealm, pszParmValue);
+       ret &= string_set(&Globals.szRealmUpper, realm);
+       ret &= string_set(&Globals.szDnsDomain, dnsdomain);
+       TALLOC_FREE(realm);
+       TALLOC_FREE(dnsdomain);
+
+       return ret;
+}
+
 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
 {
        bool ret;
diff --git a/source3/param/loadparm_ctx.c b/source3/param/loadparm_ctx.c
new file mode 100644 (file)
index 0000000..3bcf809
--- /dev/null
@@ -0,0 +1,43 @@
+#include "includes.h"
+#include "../source4/param/s3_param.h"
+
+/* These are in the order that they appear in the s4 loadparm file.
+ * All of the s4 loadparm functions should be here eventually, once
+ * they are implemented in the s3 loadparm, have the same format (enum
+ * values in particular) and defaults. */
+static const struct loadparm_s3_context s3_fns = 
+{
+       .server_role = lp_server_role,
+
+       .winbind_separator = lp_winbind_separator,
+       .template_homedir = lp_template_homedir,
+       .template_shell = lp_template_shell,
+
+       .dos_charset = lp_dos_charset,
+       .unix_charset = lp_unix_charset,
+       .display_charset = lp_display_charset,
+
+       .realm = lp_realm,
+       .dnsdomain = lp_dnsdomain,
+       .socket_options = lp_socket_options,
+       .workgroup = lp_workgroup,
+
+       .netbios_name = global_myname,
+       .netbios_scope = global_scope,
+
+       .lanman_auth = lp_lanman_auth,
+       .ntlm_auth = lp_ntlm_auth,
+
+       .client_plaintext_auth = lp_client_plaintext_auth,
+       .client_lanman_auth = lp_client_lanman_auth,
+       .client_ntlmv2_auth = lp_client_ntlmv2_auth,
+
+       .private_dir = lp_private_dir,
+       .ncalrpc_dir = lp_ncalrpc_dir,
+       .lockdir = lp_lockdir
+};
+
+const struct loadparm_s3_context *loadparm_s3_context(void)
+{
+       return &s3_fns;
+}
index 4fd7a7b5568cf8c093d99e9fa816ce6955710293..b30c204ab3ef994163932740df44dee8a9a073e2 100755 (executable)
@@ -737,9 +737,15 @@ bld.SAMBA3_SUBSYSTEM('PARAM_UTIL',
                     source=PARAM_UTIL_SRC,
                     deps='samba-util-common')
 
+if bld.env.toplevel_build:
+    bld.SAMBA3_SUBSYSTEM('LOADPARM_CTX',
+                         source='param/loadparm_ctx.c',
+                         deps='''s3_param_h PARAM_WITHOUT_REG''',
+                         vars=locals())
+
 bld.SAMBA3_SUBSYSTEM('PARAM_WITHOUT_REG',
                     source=PARAM_WITHOUT_REG_SRC,
-                    deps='''PARAM_UTIL smbd_conn ldap lber''',
+                    deps='''PARAM_UTIL smbd_conn ldap lber LOADPARM_CTX''',
                     vars=locals())
 
 bld.SAMBA3_SUBSYSTEM('param',
@@ -1410,7 +1416,7 @@ if not bld.env.toplevel_build:
     bld.SAMBA3_SUBSYSTEM('ldb', source='', deps='ldb3')
     bld.SAMBA3_SUBSYSTEM('dcerpc', '', deps='UTIL_TEVENT')
     bld.SAMBA3_SUBSYSTEM('cli-ldap', '', deps='UTIL_TEVENT')
-
+    bld.SAMBA3_SUBSYSTEM('LOADPARM_CTX', '')
 
 ########################## INCLUDES #################################
 
index d5c82354afb2045de93e81b0d2810754b809e3b2..6a173b1afca708e283b41c7fce27e7f8565e191c 100644 (file)
@@ -68,6 +68,7 @@
 #include "rpc_server/common/common.h"
 #include "lib/socket/socket.h"
 #include "auth/gensec/gensec.h"
+#include "s3_param.h"
 
 #define standard_sub_basic talloc_strdup
 
@@ -520,6 +521,7 @@ struct loadparm_context {
        bool refuse_free;
        bool global; /* Is this the global context, which may set
                      * global variables such as debug level etc? */
+       struct loadparm_s3_context *s3_fns;
 };
 
 
@@ -601,32 +603,78 @@ static struct loadparm_context *global_loadparm_context;
 #define lpcfg_default_service global_loadparm_context->sDefault
 #define lpcfg_global_service(i) global_loadparm_context->services[i]
 
-#define FN_GLOBAL_STRING(fn_name,var_name) \
- _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return NULL; return lp_ctx->globals->var_name ? lp_string(lp_ctx->globals->var_name) : "";}
+#define FN_GLOBAL_STRING(fn_name,var_name)                             \
+ _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) { \
+       if (lp_ctx == NULL) return NULL;                                \
+       if (lp_ctx->s3_fns) {                                           \
+               SMB_ASSERT(lp_ctx->s3_fns->fn_name);                    \
+               return lp_ctx->s3_fns->fn_name();                       \
+       }                                                               \
+       return lp_ctx->globals->var_name ? lp_string(lp_ctx->globals->var_name) : ""; \
+}
 
 #define FN_GLOBAL_CONST_STRING(fn_name,var_name) \
- _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return NULL; return lp_ctx->globals->var_name ? lp_ctx->globals->var_name : "";}
-
-#define FN_GLOBAL_LIST(fn_name,var_name) \
- _PUBLIC_ const char **lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return NULL; return lp_ctx->globals->var_name;}
+ _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {\
+        if (lp_ctx == NULL) return NULL;                               \
+        if (lp_ctx->s3_fns) {                                          \
+                SMB_ASSERT(lp_ctx->s3_fns->fn_name);                   \
+                return lp_ctx->s3_fns->fn_name();                      \
+        }                                                              \
+        return lp_ctx->globals->var_name ? lp_string(lp_ctx->globals->var_name) : ""; \
+ }
+
+#define FN_GLOBAL_LIST(fn_name,var_name)                               \
+ _PUBLIC_ const char **lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) { \
+        if (lp_ctx == NULL) return NULL;                               \
+        if (lp_ctx->s3_fns) {                                          \
+                SMB_ASSERT(lp_ctx->s3_fns->fn_name);                   \
+                return lp_ctx->s3_fns->fn_name();                      \
+        }                                                              \
+        return lp_ctx->globals->var_name;                              \
+ }
 
 #define FN_GLOBAL_BOOL(fn_name,var_name) \
- _PUBLIC_ bool lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return false; return lp_ctx->globals->var_name;}
+ _PUBLIC_ bool lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {\
+        if (lp_ctx == NULL) return false;                              \
+        if (lp_ctx->s3_fns) {                                          \
+                SMB_ASSERT(lp_ctx->s3_fns->fn_name);                   \
+                return lp_ctx->s3_fns->fn_name();                      \
+        }                                                              \
+        return lp_ctx->globals->var_name;                              \
+}
 
 #define FN_GLOBAL_INTEGER(fn_name,var_name) \
- _PUBLIC_ int lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {return lp_ctx->globals->var_name;}
+ _PUBLIC_ int lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) { \
+        if (lp_ctx->s3_fns) {                                          \
+                SMB_ASSERT(lp_ctx->s3_fns->fn_name);                   \
+                return lp_ctx->s3_fns->fn_name();                      \
+        }                                                              \
+        return lp_ctx->globals->var_name;                              \
+ }
 
 #define FN_LOCAL_STRING(fn_name,val) \
- _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_service *service, struct loadparm_service *sDefault) {return(lp_string((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault->val)));}
+ _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_service *service, \
+                                       struct loadparm_service *sDefault) { \
+        return(lp_string((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault->val))); \
+ }
 
 #define FN_LOCAL_LIST(fn_name,val) \
- _PUBLIC_ const char **lpcfg_ ## fn_name(struct loadparm_service *service, struct loadparm_service *sDefault) {return(const char **)(service != NULL && service->val != NULL? service->val : sDefault->val);}
+ _PUBLIC_ const char **lpcfg_ ## fn_name(struct loadparm_service *service, \
+                                        struct loadparm_service *sDefault) {\
+        return(const char **)(service != NULL && service->val != NULL? service->val : sDefault->val); \
+ }
 
 #define FN_LOCAL_BOOL(fn_name,val) \
- _PUBLIC_ bool lpcfg_ ## fn_name(struct loadparm_service *service, struct loadparm_service *sDefault) {return((service != NULL)? service->val : sDefault->val);}
+ _PUBLIC_ bool lpcfg_ ## fn_name(struct loadparm_service *service, \
+                                struct loadparm_service *sDefault) {   \
+        return((service != NULL)? service->val : sDefault->val); \
+ }
 
 #define FN_LOCAL_INTEGER(fn_name,val) \
- _PUBLIC_ int lpcfg_ ## fn_name(struct loadparm_service *service, struct loadparm_service *sDefault) {return((service != NULL)? service->val : sDefault->val);}
+ _PUBLIC_ int lpcfg_ ## fn_name(struct loadparm_service *service, \
+                               struct loadparm_service *sDefault) {    \
+        return((service != NULL)? service->val : sDefault->val); \
+ }
 
 FN_GLOBAL_INTEGER(server_role, server_role)
 FN_GLOBAL_LIST(smb_ports, smb_ports)
@@ -2560,6 +2608,20 @@ struct loadparm_context *loadparm_init_global(bool load_default)
        return global_loadparm_context;
 }
 
+/**
+ * Initialise the global parameter structure.
+ */
+struct loadparm_context *loadparm_init_s3(TALLOC_CTX *mem_ctx, 
+                                         struct loadparm_s3_context *s3_fns)
+{
+       struct loadparm_context *loadparm_context = loadparm_init(mem_ctx);
+       if (!loadparm_context) {
+               return NULL;
+       }
+       loadparm_context->s3_fns = s3_fns;
+       return loadparm_context;
+}
+
 const char *lpcfg_configfile(struct loadparm_context *lp_ctx)
 {
        return lp_ctx->szConfigFile;
index 79a1bff2c73365aa56cffe5a0f4fda0e6fcb52f1..f8ce15d7b611f0aa7090c2bcf85ab580ee4d7423 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef _PARAM_H /* _PARAM_H */
 #define _PARAM_H 
 
+struct loadparm_s3_context;
+
 struct parmlist_entry;
 
 struct param_context {
index 72674e5574040e7f02f84d01f90da383dc2cdd07..98e838133e62df28a17eb09acb730c3a7dc8b6a4 100644 (file)
@@ -1,5 +1,10 @@
 #!/usr/bin/env python
 
+bld.SAMBA_GENERATOR('s3_param_h',
+                    source= 'loadparm.c ../script/mks3param.pl',
+                    target='s3_param.h',
+                    rule='${PERL} ${SRC[1].abspath(env)} ${SRC[0].abspath(env)} --file ${TGT}')
+
 bld.SAMBA_LIBRARY('samba-hostconfig',
        source='loadparm.c generic.c util.c',
        pc_files='samba-hostconfig.pc',
diff --git a/source4/script/mks3param.pl b/source4/script/mks3param.pl
new file mode 100644 (file)
index 0000000..db494e7
--- /dev/null
@@ -0,0 +1,175 @@
+#!/usr/bin/perl
+# Simple script for generating prototypes for C functions
+# Written by Jelmer Vernooij
+# based on the original mkproto.sh by Andrew Tridgell
+
+use strict;
+
+# don't use warnings module as it is not portable enough
+# use warnings;
+
+use Getopt::Long;
+use File::Basename;
+use File::Path;
+
+#####################################################################
+# read a file into a string
+
+my $file = undef;
+my $public_define = undef;
+my $_public = "";
+my $_private = "";
+my $public_data = \$_public;
+my $builddir = ".";
+my $srcdir = ".";
+
+sub public($)
+{
+       my ($d) = @_;
+       $$public_data .= $d;
+}
+
+sub usage()
+{
+       print "Usage: mks3param.pl [options] [c files]\n";
+       print "OPTIONS:\n";
+       print "  --srcdir=path          Read files relative to this directory\n";
+       print "  --builddir=path        Write file relative to this directory\n";
+       print "  --help                 Print this help message\n\n";
+       exit 0;
+}
+
+GetOptions(
+       'file=s' => sub { my ($f,$v) = @_; $file = $v; },
+       'srcdir=s' => sub { my ($f,$v) = @_; $srcdir = $v; },
+       'builddir=s' => sub { my ($f,$v) = @_; $builddir = $v; },
+       'help' => \&usage
+) or exit(1);
+
+sub normalize_define($$)
+{
+       my ($define, $file) = @_;
+
+       if (not defined($define) and defined($file)) {
+               $define = "__" . uc($file) . "__";
+               $define =~ tr{./}{__};
+               $define =~ tr{\-}{_};
+       } elsif (not defined($define)) {
+               $define = '_S3_PARAM_H_';
+       }
+
+       return $define;
+}
+
+$public_define = normalize_define($public_define, $file);
+
+sub file_load($)
+{
+    my($filename) = @_;
+    local(*INPUTFILE);
+    open(INPUTFILE, $filename) or return undef;
+    my($saved_delim) = $/;
+    undef $/;
+    my($data) = <INPUTFILE>;
+    close(INPUTFILE);
+    $/ = $saved_delim;
+    return $data;
+}
+
+sub print_header($$)
+{
+       my ($file, $header_name) = @_;
+       $file->("#ifndef $header_name\n");
+       $file->("#define $header_name\n\n");
+       $file->("/* This file was automatically generated by mks3param.pl. DO NOT EDIT */\n\n");
+       $file->("struct loadparm_s3_context\n");
+       $file->("{\n");
+}
+
+sub print_footer($$) 
+{
+       my ($file, $header_name) = @_;
+       $file->("};");
+       $file->("\n#endif /* $header_name */\n\n");
+}
+
+sub handle_loadparm($$) 
+{
+       my ($file,$line) = @_;
+
+       if ($line =~ /^FN_(GLOBAL|LOCAL)_(CONST_STRING|STRING|BOOL|bool|CHAR|INTEGER|LIST)\((\w+),.*\)/o) {
+               my $scope = $1;
+               my $type = $2;
+               my $name = $3;
+
+               my %tmap = (
+                           "BOOL" => "bool ",
+                           "CONST_STRING" => "const char *",
+                           "STRING" => "const char *",
+                           "INTEGER" => "int ",
+                           "CHAR" => "char ",
+                           "LIST" => "const char **",
+                           );
+
+               $file->("\t$tmap{$type} (*$name)(void);\n");
+       }
+}
+
+sub process_file($$) 
+{
+       my ($file, $filename) = @_;
+
+       $filename =~ s/\.o$/\.c/g;
+
+       if ($filename =~ /^\//) {
+               open(FH, "<$filename") or die("Failed to open $filename");
+       } elsif (!open(FH, "< $builddir/$filename")) {
+           open(FH, "< $srcdir/$filename") || die "Failed to open $filename";
+       }
+
+       my $comment = undef;
+       my $incomment = 0;
+       while (my $line = <FH>) {             
+               if ($line =~ /^\/\*\*/) { 
+                       $comment = "";
+                       $incomment = 1;
+               }
+
+               if ($incomment) {
+                       $comment .= $line;
+                       if ($line =~ /\*\//) {
+                               $incomment = 0;
+                       }
+               } 
+
+               # these are ordered for maximum speed
+               next if ($line =~ /^\s/);
+             
+               next unless ($line =~ /\(/);
+
+               next if ($line =~ /^\/|[;]/);
+
+               if ($line =~ /^FN_/) {
+                       handle_loadparm($file, $line);
+               }
+               next;
+       }
+
+       close(FH);
+}
+
+
+print_header(\&public, $public_define);
+
+process_file(\&public, $_) foreach (@ARGV);
+print_footer(\&public, $public_define);
+
+if (not defined($file)) {
+       print STDOUT $$public_data;
+}
+
+mkpath(dirname($file), 0, 0755);
+open(PUBLIC, ">$file") or die("Can't open `$file': $!"); 
+print PUBLIC "$$public_data";
+close(PUBLIC);
+