The branch, master has been updated
       via  6ba2426 WHATSNEW: Add info for 'net ads keytab' and 'net ads 
setspn' changes
       via  0a19e8b docs: Add manpage for new 'net ads setspn' subcommand
       via  f542749 docs: Add manpage for 'net ads keytab' subcommand
       via  ebe9a86 testprogs: 'net ads keytab create' expected failures should 
now pass
       via  0af6645 s3:libads: 'net ads keytab create' shouldn't write SPN(s)
       via  284f550 testprogs: Switch expected failure tests to expected pass
       via  5adb29f s3:utils: Modify default behaviour of 'net ads keytab add'
       via  4e518ec s3:libads: add param to prevent writing spn(s) to ads
       via  53190e9 testprogs:: Add blackbox tests for 'net ads keytab add'
       via  6cac9a4 s3:libads: Allow 'net ads keytab add' handle Windows SPN(s) 
part 2
       via  efabfb1 s3:libads: Allow 'net ads keytab add' handle Windows SPN(s) 
part 1
       via  21889ca testprocs/blackbox: Add tests for net ads setspn 
(add|delete|list)
       via  5fa8226 s3:utils: add new 'net ads setspn delete' subcommand
       via  8a6c3c5 s3:utils: add new 'net ads setspn add' subcommand
       via  65ef044 s3:utils: add new 'net ads setspn list' subcommand
       via  1400ab7 s3:libads: change ads_add_service_principal_name 
implementation
       via  cf0823f s3:libads: Add a basic Windows SPN parser.
       via  d959380 s3:libads: Clean up code a little rename 
'ads_get_samaccountname()'
       via  2dd94e4 s3:libads: ads_get_dnshostname & ads_get_samaccountname 
don't use param
       via  ba6a825 tests: Add basic ms_fnmatch unit test
       via  ea893be util: Fix the logic in ms_fnmatch_protocol()
      from  f3b650f Fix autobuild for user names starting with c

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 6ba2426089f6711ea058ecb9ace07cc057e671b6
Author: Noel Power <noel.po...@suse.com>
Date:   Mon Feb 12 16:38:56 2018 +0000

    WHATSNEW: Add info for 'net ads keytab' and 'net ads setspn' changes
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>
    
    Autobuild-User(master): Andreas Schneider <a...@cryptomilk.org>
    Autobuild-Date(master): Fri Mar  2 19:12:08 CET 2018 on sn-devel-144

commit 0a19e8b467982b04f68b6ad0525ab20a5a29b7b3
Author: Noel Power <noel.po...@suse.com>
Date:   Mon Feb 12 13:53:19 2018 +0000

    docs: Add manpage for new 'net ads setspn' subcommand
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit f542749acde5be0d2e77e05bec2c5b112c5ef282
Author: Noel Power <noel.po...@suse.com>
Date:   Mon Feb 12 12:13:02 2018 +0000

    docs: Add manpage for 'net ads keytab' subcommand
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit ebe9a86eadca37313dd85d9b317197bb7fa2b7e5
Author: Noel Power <noel.po...@suse.com>
Date:   Fri Feb 16 15:53:16 2018 +0000

    testprogs: 'net ads keytab create' expected failures should now pass
    
    Following the commit to change the behaviour of 'net ads keytab create'
    some tests previously failing should now pass.
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit 0af66455ef87626b97689d75d17782d95455b55e
Author: Noel Power <noel.po...@suse.com>
Date:   Fri Feb 9 14:07:27 2018 +0000

    s3:libads: 'net ads keytab create' shouldn't write SPN(s)
    
    Modify default behaviour of 'net ads keytab create'
    
    The change modifies the behaviour of 'net ads keytab create' such
    that only the keytab file is modified. The current behaviour doesn't
    make sense, existing SPN(s) pulled from the computer AD object have
    the format 'serviceclass/host:port/servicename'.
    'ads_keytab_create_default' calls ads_keytab_add_entry passing
    'serviceclass' for each SPN retrieved from the AD. For each
    serviceclass passed in a new pair of SPN(s) is generated as follows
        i) long form 'param/full_qualified_dns'
       ii) short form 'param/netbios_name'
    
    This doesn't make sense as we are creating a new SPN(s) from an existing
    one probably replacing the existing host with the 'client' machine.
    
    If the keytab file exists then additionally each kerberos principal in the
    keytab file is parsed to strip out the primary, then 'ads_keytab_add_entry'
    is called which then tries by default to generate a SPN from any primary
    that doesn't end in '$'. By default those SPNs are then added to the AD
    computer account for the client running the command.
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit 284f5508a9563341817291aabf2640d05c2e8594
Author: Noel Power <noel.po...@suse.com>
Date:   Fri Feb 16 15:50:03 2018 +0000

    testprogs: Switch expected failure tests to expected pass
    
    Following the commit to change the behaviour of 'net ads keytab add' and
    new 'keytab add_update_ads' some tests previously failing should now
    pass.
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit 5adb29f242dde67865017ec8d45852a1fa290ebf
Author: Noel Power <noel.po...@suse.com>
Date:   Fri Feb 9 14:03:33 2018 +0000

    s3:utils: Modify default behaviour of 'net ads keytab add'
    
    This change modifies the behaviour of 'net ads keytab add' such
    that only the keytab file is modified.
    
    A new command 'net ads keytab add_update_ads' has been added that
    preserves the legacy behaviour which can update the AD computer
    object with Winows SPN(s) as appropriate. Alternatively the new
    command 'net ads setspn add' can be used to manually add the
    windows SPN(s) that previously would have been added.
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit 4e518ecdda040e1aa47506e436255597437a05ed
Author: Noel Power <noel.po...@suse.com>
Date:   Thu Feb 8 17:33:08 2018 +0000

    s3:libads: add param to prevent writing spn(s) to ads
    
    'net ads keytab add' currently in addition to adding to the
    keytab file this command also can update AD computer objects
    via ldap. This behaviour isn't very intuitive or expected given
    the command name. By default we shouldn't write to the ADS.
    
    Prepare to change the default behaviour by modifying the function
    'ads_keytab_add_entry' to take a paramater to modify the existing
    behaviour to optionally update the AD (or not).
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit 53190e9a0f28b55325090fd6bb12dbfdef1fe6cd
Author: Noel Power <noel.po...@suse.com>
Date:   Wed Jan 17 17:18:15 2018 +0000

    testprogs:: Add blackbox tests for 'net ads keytab add'
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit 6cac9a4720713592ba9d0a88c39e331ec42baef4
Author: Noel Power <noel.po...@suse.com>
Date:   Mon Jan 29 18:38:05 2018 +0000

    s3:libads: Allow 'net ads keytab add' handle Windows SPN(s) part 2
    
    This patch addresses how the windows SPN is written to the AD.
    
    If a legacy service (e.g. cifs, http etc.) is passed as param to
    'net ads keytab add param' then windows SPNs are generated from
    'param' as follows
              i) long form 'param/full_qualified_dns'
             ii) short form 'param/netbios_name'
    
    If the SPN is a is a Windows SPN (e.g. conforming to format
    'serviceclass/host:port') then this is the SPN that is passed to
    the AD.
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit efabfb1c17b02c2e567e8e351e52aa8ba69d7c34
Author: Noel Power <noel.po...@suse.com>
Date:   Mon Jan 29 18:30:33 2018 +0000

    s3:libads: Allow 'net ads keytab add' handle Windows SPN(s) part 1
    
    This patch addresses how the windows SPN is converted into a kerberos
    priniciple to be written to the keytab file. A followup patch will
    deal with writing Window SPN(s) to the AD.
    
    Before this change 'net ads keytab add' handled three scenarios
    
    a) 'net ads keytab add param' is passed a fully qualified kerberos principal
       (identified by the presence of '@' in param) In this scenario the keytab
       file alone is updated with the principal contained in 'param'.
    b) 'net ads keytab add param'; is passed a machine name (identified by
       the paramater ending with '$'). In this case the machine name
       is converted to a kerberos principal with according to the recipe
       'param@realm' where realm is determined by lp_realm().
    c) 'net ads keytab add param' is passed a service (e.g. nfs, http etc.)
       In this scenario the param containing the service is first converted to
       into 2 kerberos principals (long and short forms) according to the
       following recipe
          i) long form:  'param/fully_qualified_dns@realm'
         ii) short form: 'param/netbios_name@realm'
         where 'fully_qualified_dns is retrieved from 'dNSHostName' attribute of
         'this' machines computer account on the AD.
         The principals are written to the keytab file
       Secondly 2 windows SPNs are generated from 'param' as follows
          i) long form 'param/full_qualified_dns'
         ii) short form 'param/netbios_name'
       These SPNs are written to the AD computer account object
    
    After this change a) & b) & c) will retain legacy behaviour except
    in the case of c) where if the 'param' passed to c) is a Windows SPN
    (e.g. conforming to format 'serviceclass/host:port'
      i) 'param' will get converted to a kerberos principal (just a single one)
         with the following recipe: 'serviceclass/host@realm' which will
         be written to the keytab file. The SPN written to the AD is created
         as before and the legacy behaviour is preserved.
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit 21889ca21ce483ef53210273a212466882855181
Author: Noel Power <noel.po...@suse.com>
Date:   Thu Jan 18 11:30:50 2018 +0000

    testprocs/blackbox: Add tests for net ads setspn (add|delete|list)
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit 5fa82263ad6bc82c9a8b34797df35bd800b7f11f
Author: Noel Power <noel.po...@suse.com>
Date:   Wed Jan 24 14:51:03 2018 +0000

    s3:utils: add new 'net ads setspn delete' subcommand
    
    This patch adds 'delete' to the 'net ads setspn' subcommand
    
    (see 
https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/cc731241(v=ws.11)
    
    Usage:
    
        net ads setspn delete <computer> <SPN>
    
    Note: <computer> is optional, if not specified the computer account
    associated with value returned by lp_netbios_name() is used instead.
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit 8a6c3c5ae2cab809d994821ed573315ba0c7562d
Author: Noel Power <noel.po...@suse.com>
Date:   Wed Jan 24 14:41:06 2018 +0000

    s3:utils: add new 'net ads setspn add' subcommand
    
    This patch adds 'add' to the 'net ads setspn' subcommand
    
    (see 
https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/cc731241(v=ws.11)
    
    Usage:
    
         net ads setspn add <computer> <SPN>
    
    Note: <computer> is optional, if not specified the computer account
    associated with value returned by lp_netbios_name() is used instead.
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit 65ef044b8dba40e118446a0c700cffcf9bd81330
Author: Noel Power <noel.po...@suse.com>
Date:   Wed Jan 24 14:26:03 2018 +0000

    s3:utils: add new 'net ads setspn list' subcommand
    
    This patch adds basic functionality not unlike the setspn.exe
    command that is provided by windows for adminsistering SPN on
    the AD. (see 
https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/cc731241(v=ws.11)
    
    Only the basic list operation (that corresponds to the -l
        switch for setspn.exe is implemented)
    
    Usage:
    
         net ads setspn list <computer>
    
    Note: <computer> is optional, if not specified the computer account
    associated with value returned by lp_netbios_name() is used instead.
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit 1400ab709e37e02f1d108f46779d49ba895ba8b1
Author: Noel Power <noel.po...@suse.com>
Date:   Fri Feb 16 16:52:01 2018 +0000

    s3:libads: change ads_add_service_principal_name implementation
    
    Previously the function 'ads_add_service_principal_name' created
    the SPNs based on the machine_name and dns name passed to the function.
    In order to prepare for a future patch that will also need to write
    SPN(s) to the AD computer account, the function implementation will
    need to be changed. Instead of the function creating the SPN(s) it
    will now take the list SPN(s) to write to the AD 'machine_name' account
    as an input param instead.
    The name of the function has been changed to
    'ads_add_service_principal_names' to reflect this. Additionally  client
    code now needs to construct the SPNs to be passed into the function.
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit cf0823fb9ee169efd6b268709c955db674e0cdbb
Author: Noel Power <noel.po...@suse.com>
Date:   Mon Jan 29 17:51:15 2018 +0000

    s3:libads: Add a basic Windows SPN parser.
    
    (see 
https://social.technet.microsoft.com/wiki/contents/articles/717.service-principal-names-spns-setspn-syntax-setspn-exe.aspx)
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit d9593803eadb9a3d4ee4448a2b39ffdd056b68af
Author: Noel Power <noel.po...@suse.com>
Date:   Fri Jan 12 14:22:34 2018 +0000

    s3:libads: Clean up code a little rename 'ads_get_samaccountname()'
    
    Function 'ads_get_samaccountname()' basically returns the machine_name 
passed
    as an input param (appended with '$') if it exists on the ad. The function
    really is testing for the existence of the samaccountname and is not really
    'getting' it. This is also the way it is used. Renaming this function to
    'ads_has_samaccountname()' better reflects what it is actually doing and how
    clients calling the code use it. It also makes the client code using calling
    this function less confusing.
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit 2dd94e41f6e76b4cbbeb1704778a8c27b6eb35f4
Author: Noel Power <noel.po...@suse.com>
Date:   Fri Jan 12 12:22:45 2018 +0000

    s3:libads: ads_get_dnshostname & ads_get_samaccountname don't use param
    
    Both ads_get_dnshostname() & ads_get_samaccountname() are passed
    a param machinename as a argument. Instead of using 'machinename' these
    functions are erroneously using lp_netbiosname() instead.
    
    Signed-off-by: Noel Power <noel.po...@suse.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit ba6a82570abcde912712eb2830aed4eef4fbf491
Author: David Disseldorp <dd...@samba.org>
Date:   Tue Feb 20 11:08:47 2018 +0100

    tests: Add basic ms_fnmatch unit test
    
    Pair-Programmed-With: Andreas Schneider <a...@samba.org>
    
    Signed-off-by: David Disseldorp <dd...@samba.org>
    Signed-off-by: Andreas Schneider <a...@samba.org>

commit ea893be35a909c35d5a977a5abd76cb48e24eed6
Author: Andreas Schneider <a...@samba.org>
Date:   Thu Oct 26 09:47:57 2017 +0200

    util: Fix the logic in ms_fnmatch_protocol()
    
    Make sure we always pass a valid max_n pointer to ms_fnmatch_core().
    
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: David Disseldorp <dd...@samba.org>

-----------------------------------------------------------------------

Summary of changes:
 WHATSNEW.txt                       |  36 ++++++
 docs-xml/manpages/net.8.xml        | 116 +++++++++++++++++++
 lib/util/ms_fnmatch.c              |   9 +-
 lib/util/tests/test_ms_fnmatch.c   | 113 ++++++++++++++++++
 lib/util/wscript_build             |   6 +
 selftest/tests.py                  |   2 +
 source3/libads/ads_proto.h         |  26 ++++-
 source3/libads/kerberos_keytab.c   | 207 +++++++++++++++++++++++++++------
 source3/libads/ldap.c              |  68 ++++-------
 source3/libads/net_ads_setspn.c    | 229 +++++++++++++++++++++++++++++++++++++
 source3/libads/util.c              | 103 +++++++++++++++++
 source3/utils/net_ads.c            | 174 +++++++++++++++++++++++++++-
 source3/utils/net_proto.h          |   1 +
 source3/wscript_build              |   1 +
 testprogs/blackbox/test_net_ads.sh |  98 ++++++++++++++++
 15 files changed, 1102 insertions(+), 87 deletions(-)
 create mode 100644 lib/util/tests/test_ms_fnmatch.c
 create mode 100644 source3/libads/net_ads_setspn.c


Changeset truncated at 500 lines:

diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index ad045e3..7bd3792 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -17,6 +17,42 @@ NEW FEATURES/CHANGES
 ====================
 
 
+net ads setspn
+---------------
+
+There is a new 'net ads setspn' sub command for managing Windows SPN(s)
+on the AD. This command aims to give the basic functionaility that is
+provided on windows by 'setspn.exe' e.g. ability to add, delete and list
+Windows SPN(s) stored in a Windows AD Computer object.
+
+The format of the command is:
+
+net ads setspn list [machine]
+net ads setspn [add | delete ] SPN [machine]
+
+'machine' is the name of the computer account on the AD that is to be managed.
+If 'machine' is not specified the name of the 'client' running the command
+is used instead.
+
+The format of a Windows SPN is
+  'serviceclass/host:port/servicename' (servicename and port are optional)
+
+serviceclass/host is generally sufficient to specify a host based service.
+
+net ads keytab changes
+----------------------
+net ads keytab add no longer attempts to convert the passed serviceclass
+(e.g. nfs, html etc.) into a Windows SPN which is added to the Windows AD
+computer object. By default just the keytab file is modified.
+
+A new keytab subcommand 'add_update_ads' has been added to preserve the
+legacy behaviour. However the new 'net ads setspn add' subcommand should
+really be used instead.
+
+net ads keytab create no longer tries to generate SPN(s) from existing
+entries in a keytab file. If it is required to add Windows SPN(s) then
+'net ads setspn add' should be used instead.
+
 REMOVED FEATURES
 ================
 
diff --git a/docs-xml/manpages/net.8.xml b/docs-xml/manpages/net.8.xml
index 542dac5..155c4fc 100644
--- a/docs-xml/manpages/net.8.xml
+++ b/docs-xml/manpages/net.8.xml
@@ -1339,6 +1339,122 @@ to show in the result.
 </refsect2>
 
 <refsect2>
+<title>ADS KEYTAB <replaceable>CREATE</replaceable></title>
+
+<para>
+Creates a new keytab file if one doesn't exist with default entries. Default
+entries are kerberos principals created from the machinename of the
+client, the UPN (if it exists) and any Windows SPN(s) associated with the
+computer AD account for the client. If a keytab file already exists then only
+missing kerberos principals from the default entries are added. No changes
+are made to the computer AD account.
+</para>
+</refsect2>
+
+<refsect2>
+<title>ADS KEYTAB <replaceable>ADD</replaceable> <replaceable>(principal | 
machine | serviceclass | windows SPN</replaceable></title>
+
+<para>
+Adds a new keytab entry, the entry can be either;
+  <variablelist>
+    <varlistentry><term>kerberos principal</term>
+    <listitem><para>
+      A kerberos principal (identified by the presence of '@') is just
+      added to the keytab file.
+    </para></listitem>
+    </varlistentry>
+    <varlistentry><term>machinename</term>
+    <listitem><para>
+      A machinename (identified by the trailing '$') is used to create a
+      a kerberos principal 'machinename@realm' which is added to the
+      keytab file.
+    </para></listitem>
+    </varlistentry>
+    <varlistentry><term>serviceclass</term>
+    <listitem><para>
+    A serviceclass (such as 'cifs', 'html' etc.) is used to create a pair
+    of kerberos principals 'serviceclass/fully_qualified_dns_name@realm' &amp;
+    'serviceclass/netbios_name@realm' which are added to the keytab file.
+    </para></listitem>
+    </varlistentry>
+    <varlistentry><term>Windows SPN</term>
+    <listitem><para>
+    A Windows SPN is of the format 'serviceclass/host:port', it is used to
+    create a kerberos principal 'serviceclass/host@realm' which will
+    be written to the keytab file.
+    </para></listitem>
+    </varlistentry>
+  </variablelist>
+</para>
+<para>
+Unlike old versions no computer AD objects are modified by this command. To
+preserve the bevhaviour of older clients 'net ads keytab ad_update_ads' is
+available.
+</para>
+</refsect2>
+
+<refsect2>
+<title>ADS KEYTAB <replaceable>ADD_UPDATE_ADS</replaceable> 
<replaceable>(principal | machine | serviceclass | windows 
SPN</replaceable></title>
+
+<para>
+Adds a new keytab entry (see section for net ads keytab add). In addition to
+adding entries to the keytab file corrosponding Windows SPNs are created
+from the entry passed to this command. These SPN(s) added to the AD computer
+account object associated with the client machine running this command for
+the following entry types;
+  <variablelist>
+    <varlistentry><term>serviceclass</term>
+    <listitem><para>
+    A serviceclass (such as 'cifs', 'html' etc.) is used to create a
+    pair of Windows SPN(s) 'param/full_qualified_dns' &amp;
+    'param/netbios_name' which are added to the AD computer account object
+   for this client.
+    </para></listitem>
+    </varlistentry>
+    <varlistentry><term>Windows SPN</term>
+    <listitem><para>
+    A Windows SPN is of the format 'serviceclass/host:port', it is
+    added as passed to the AD computer account object for this client.
+    </para></listitem>
+    </varlistentry>
+  </variablelist>
+</para>
+</refsect2>
+
+<refsect2>
+<title>ADS setspn <replaceable>SETSPN LIST [machine]</replaceable></title>
+
+<para>
+   Lists the Windows SPNs stored in the 'machine' Windows AD Computer object.
+   If 'machine' is not specified then computer account for this client is used
+   instead.
+</para>
+</refsect2>
+
+<refsect2>
+<title>ADS setspn <replaceable>SETSPN ADD SPN [machine]</replaceable></title>
+
+<para>
+   Adds the specified Windows SPN to the 'machine' Windows AD Computer object.
+   If 'machine' is not specified then computer account for this client is used
+   instead.
+</para>
+</refsect2>
+
+
+<refsect2>
+<title>ADS setspn <replaceable>SETSPN DELETE SPN 
[machine]</replaceable></title>
+
+<para>
+   DELETE the specified Window SPN from the 'machine' Windows AD Computer
+   object. If 'machine' is not specified then computer account for this
+   client is used
+   instead.
+</para>
+
+</refsect2>
+
+<refsect2>
 <title>ADS WORKGROUP</title>
 
 <para>Print out workgroup name for specified kerberos realm.</para>
diff --git a/lib/util/ms_fnmatch.c b/lib/util/ms_fnmatch.c
index c0f61ab..636ac39 100644
--- a/lib/util/ms_fnmatch.c
+++ b/lib/util/ms_fnmatch.c
@@ -164,7 +164,8 @@ static int ms_fnmatch_core(const char *p, const char *n,
 int ms_fnmatch_protocol(const char *pattern, const char *string, int protocol,
                        bool is_case_sensitive)
 {
-       int ret, count, i;
+       int ret = -1;
+       size_t count, i;
 
        if (strcmp(string, "..") == 0) {
                string = ".";
@@ -209,13 +210,17 @@ int ms_fnmatch_protocol(const char *pattern, const char 
*string, int protocol,
                if (pattern[i] == '*' || pattern[i] == '<') count++;
        }
 
-       {
+       /* If the pattern includes '*' or '<' */
+       if (count >= 1) {
                struct max_n max_n[count];
 
                memset(max_n, 0, sizeof(struct max_n) * count);
 
                ret = ms_fnmatch_core(pattern, string, max_n, strrchr(string, 
'.'),
                                      is_case_sensitive);
+       } else {
+               ret = ms_fnmatch_core(pattern, string, NULL, strrchr(string, 
'.'),
+                                     is_case_sensitive);
        }
 
        return ret;
diff --git a/lib/util/tests/test_ms_fnmatch.c b/lib/util/tests/test_ms_fnmatch.c
new file mode 100644
index 0000000..7fe8ed0
--- /dev/null
+++ b/lib/util/tests/test_ms_fnmatch.c
@@ -0,0 +1,113 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Copyright (C) 2018      David Disseldorp <dd...@samba.org>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include <errno.h>
+
+#include "lib/replace/replace.h"
+#include "lib/util/samba_util.h"
+#include "libcli/smb/smb_constants.h"
+
+static void test_ms_fn_match_protocol_no_wildcard(void **state)
+{
+       int cmp;
+
+       /* no wildcards in pattern, a simple strcasecmp_m */
+       cmp = ms_fnmatch_protocol("pattern", "string", PROTOCOL_COREPLUS,
+                                 true);        /* case sensitive */
+       assert_int_equal(cmp, -3);
+}
+
+static void test_ms_fn_match_protocol_pattern_upgraded(void **state)
+{
+       int cmp;
+
+       /* protocol < PROTOCOL_NT1 pattern is "upgraded" */
+       cmp = ms_fnmatch_protocol("??????", "string", PROTOCOL_COREPLUS,
+                                 false);
+       assert_int_equal(cmp, 0);
+}
+
+static void test_ms_fn_match_protocol_match_zero_or_more(void **state)
+{
+       int cmp;
+
+       /* '*' matches zero or more characters. handled via recursive calls */
+       cmp = ms_fnmatch_protocol("********", "string", PROTOCOL_COREPLUS,
+                                 true);
+       assert_int_equal(cmp, 0);
+}
+
+static void test_ms_fn_match_protocol_mapped_char(void **state)
+{
+       int cmp;
+
+       /* '?' is mapped to '>', which matches any char or a '\0' */
+       cmp = ms_fnmatch_protocol("???????", "string", PROTOCOL_COREPLUS,
+                                   false);
+       assert_int_equal(cmp, 0);
+}
+
+static void test_ms_fn_match_protocol_nt1_any_char(void **state)
+{
+       int cmp;
+
+       /* PROTOCOL_NT1 '?' matches any char, '\0' is not included */
+       cmp = ms_fnmatch_protocol("???????", "string", PROTOCOL_NT1,
+                                 false);
+       assert_int_equal(cmp, -1);
+}
+
+static void test_ms_fn_match_protocol_nt1_case_sensitive(void **state)
+{
+       int cmp;
+
+       cmp = ms_fnmatch_protocol("StRinG", "string", PROTOCOL_NT1,
+                                 true);        /* case sensitive */
+       assert_int_equal(cmp, 0);
+
+       cmp = ms_fnmatch_protocol("StRin?", "string", PROTOCOL_NT1,
+                                 true);        /* case sensitive */
+       assert_int_equal(cmp, -1);
+
+       cmp = ms_fnmatch_protocol("StRin?", "string", PROTOCOL_NT1,
+                                 false);
+       assert_int_equal(cmp, 0);
+       cmp = ms_fnmatch_protocol("strin?", "string", PROTOCOL_NT1,
+                                 true);        /* case sensitive */
+       assert_int_equal(cmp, 0);
+}
+
+int main(void) {
+       const struct CMUnitTest tests[] = {
+               cmocka_unit_test(test_ms_fn_match_protocol_no_wildcard),
+               cmocka_unit_test(test_ms_fn_match_protocol_pattern_upgraded),
+               cmocka_unit_test(test_ms_fn_match_protocol_match_zero_or_more),
+               cmocka_unit_test(test_ms_fn_match_protocol_mapped_char),
+               cmocka_unit_test(test_ms_fn_match_protocol_nt1_any_char),
+               cmocka_unit_test(test_ms_fn_match_protocol_nt1_case_sensitive),
+       };
+
+       cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+       return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/lib/util/wscript_build b/lib/util/wscript_build
index d49d4a2..615ff75 100644
--- a/lib/util/wscript_build
+++ b/lib/util/wscript_build
@@ -222,3 +222,9 @@ else:
                      deps='cmocka replace samba-util',
                      local_include=False,
                      install=False)
+
+    bld.SAMBA_BINARY('test_ms_fnmatch',
+                     source='tests/test_ms_fnmatch.c',
+                     deps='cmocka replace samba-util',
+                     local_include=False,
+                     install=False)
diff --git a/selftest/tests.py b/selftest/tests.py
index 1c6921a..e69bc31 100644
--- a/selftest/tests.py
+++ b/selftest/tests.py
@@ -184,3 +184,5 @@ plantestsuite("samba.unittests.tldap", "none",
               [os.path.join(bindir(), "default/source3/test_tldap")])
 plantestsuite("samba.unittests.rfc1738", "none",
               [os.path.join(bindir(), "default/lib/util/test_rfc1738")])
+plantestsuite("samba.unittests.ms_fnmatch", "none",
+              [os.path.join(bindir(), "default/lib/util/test_ms_fnmatch")])
diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h
index b6d9d9b..154bf67 100644
--- a/source3/libads/ads_proto.h
+++ b/source3/libads/ads_proto.h
@@ -49,11 +49,19 @@ void ads_disp_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, 
struct security_descripto
 
 /* The following definitions come from libads/kerberos_keytab.c  */
 
-int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc);
+int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc,
+                        bool update_ads);
 int ads_keytab_flush(ADS_STRUCT *ads);
 int ads_keytab_create_default(ADS_STRUCT *ads);
 int ads_keytab_list(const char *keytab_name);
 
+/* The following definitions come from libads/net_ads_setspn.c  */
+bool ads_setspn_list(ADS_STRUCT *ads, const char *machine);
+bool ads_setspn_add(ADS_STRUCT *ads, const char *machine_name,
+                   const char * spn);
+bool ads_setspn_delete(ADS_STRUCT *ads, const char *machine_name,
+                      const char * spn);
+
 /* The following definitions come from libads/krb5_errs.c  */
 
 /* The following definitions come from libads/kerberos_util.c  */
@@ -95,8 +103,8 @@ ADS_STATUS ads_get_service_principal_names(TALLOC_CTX 
*mem_ctx,
                                           char ***spn_array,
                                           size_t *num_spns);
 ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char 
*machine_name);
-ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char 
*machine_name,
-                                          const char *my_fqdn, const char 
*spn);
+ADS_STATUS ads_add_service_principal_names(ADS_STRUCT *ads, const char 
*machine_name,
+                                          const char **spns);
 ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads,
                                   const char *machine_name,
                                   const char *org_unit,
@@ -121,7 +129,7 @@ ADS_STATUS ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx,
                                        struct dom_sid *sid);
 char* ads_get_dnshostname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char 
*machine_name );
 char* ads_get_upn( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name 
);
-char* ads_get_samaccountname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char 
*machine_name );
+bool ads_has_samaccountname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char 
*machine_name );
 ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name,
                        uint32_t account_type, const char *org_unit);
 ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname);
@@ -193,4 +201,14 @@ void ndr_print_ads_saslwrap_struct(struct ndr_print *ndr,
 
 ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char 
*host_principal);
 
+struct spn_struct {
+       const char *serviceclass;
+       const char *servicename;
+       const char *host;
+       int32_t port;
+};
+
+/* parse a windows style SPN, returns NULL if parsing fails */
+struct spn_struct *parse_spn(TALLOC_CTX *ctx, const char *srvprinc);
+
 #endif /* _LIBADS_ADS_PROTO_H_ */
diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c
index 37ac7ba..85f195a 100644
--- a/source3/libads/kerberos_keytab.c
+++ b/source3/libads/kerberos_keytab.c
@@ -85,11 +85,154 @@ out:
        return ret;
 }
 
+static bool fill_default_spns(TALLOC_CTX *ctx, const char *machine_name,
+                                          const char *my_fqdn, const char *spn,
+                                         const char ***spns)
+{
+       char *psp1, *psp2;
+
+       if (*spns == NULL) {
+               *spns = talloc_zero_array(ctx, const char*, 3);
+               if (spns == NULL) {
+                       return false;
+               }
+       }
+
+       psp1 = talloc_asprintf(ctx,
+                              "%s/%s",
+                              spn,
+                              machine_name);
+       if (psp1 == NULL) {
+               return false;
+       }
+
+       if (!strlower_m(&psp1[strlen(spn) + 1])) {
+               return false;
+       }
+       (*spns)[0] = psp1;
+
+       psp2 = talloc_asprintf(ctx,
+                              "%s/%s",
+                              spn,
+                              my_fqdn);
+       if (psp2 == NULL) {
+               return false;
+       }
+
+       if (!strlower_m(&psp2[strlen(spn) + 1])) {
+               return false;
+       }
+
+       (*spns)[1] = psp2;
+
+       return true;
+}
+
+static bool ads_set_machine_account_spns(TALLOC_CTX *ctx,
+                                        ADS_STRUCT *ads,
+                                        const char *service_or_spn,
+                                        const char *my_fqdn)
+{
+       const char **spn_names = NULL;
+       ADS_STATUS aderr;
+       struct spn_struct* spn_struct = NULL;
+       char *tmp = NULL;
+
+       /* SPN should have '/' */
+       tmp = strchr_m(service_or_spn, '/');
+       if (tmp != NULL) {
+               spn_struct = parse_spn(ctx, service_or_spn);
+               if (spn_struct == NULL) {
+                       return false;
+               }
+       }
+
+       DBG_INFO("Attempting to add/update '%s'\n", service_or_spn);
+
+       if (spn_struct != NULL) {
+               spn_names = talloc_zero_array(ctx, const char*, 2);
+               spn_names[0] = service_or_spn;
+       } else {
+               bool ok;
+
+               ok = fill_default_spns(ctx,
+                                      lp_netbios_name(),
+                                      my_fqdn,
+                                      service_or_spn,
+                                      &spn_names);
+               if (!ok) {
+                       return false;
+               }
+       }
+       aderr = ads_add_service_principal_names(ads,
+                                               lp_netbios_name(),
+                                               spn_names);


-- 
Samba Shared Repository

Reply via email to