From 1dfc6fa558e7735341a7095aa46e5568a4f56cfe Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 1 Jun 2011 23:22:24 +1000 Subject: s4-param Add hook between Samba3 and Samba4 loadparm systems. 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 | 5 ++ source3/param/loadparm.c | 23 +++++- source3/param/loadparm_ctx.c | 43 +++++++++++ source3/wscript_build | 10 ++- source4/param/loadparm.c | 86 ++++++++++++++++++--- source4/param/param.h | 2 + source4/param/wscript_build | 5 ++ source4/script/mks3param.pl | 175 +++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 333 insertions(+), 16 deletions(-) create mode 100644 source3/param/loadparm_ctx.c create mode 100644 source4/script/mks3param.pl diff --git a/source3/include/proto.h b/source3/include/proto.h index c6fd38dd81..f732a53655 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -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); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 350c95d9ac..dc79c36f19 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -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 index 0000000000..3bcf80954a --- /dev/null +++ b/source3/param/loadparm_ctx.c @@ -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; +} diff --git a/source3/wscript_build b/source3/wscript_build index 4fd7a7b556..b30c204ab3 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -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 ################################# diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c index d5c82354af..6a173b1afc 100644 --- a/source4/param/loadparm.c +++ b/source4/param/loadparm.c @@ -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; diff --git a/source4/param/param.h b/source4/param/param.h index 79a1bff2c7..f8ce15d7b6 100644 --- a/source4/param/param.h +++ b/source4/param/param.h @@ -20,6 +20,8 @@ #ifndef _PARAM_H /* _PARAM_H */ #define _PARAM_H +struct loadparm_s3_context; + struct parmlist_entry; struct param_context { diff --git a/source4/param/wscript_build b/source4/param/wscript_build index 72674e5574..98e838133e 100644 --- a/source4/param/wscript_build +++ b/source4/param/wscript_build @@ -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 index 0000000000..db494e7eb4 --- /dev/null +++ b/source4/script/mks3param.pl @@ -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) = ; + 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 = ) { + 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); + -- cgit