summaryrefslogtreecommitdiff
path: root/source3/nsswitch
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch')
-rw-r--r--source3/nsswitch/libwbclient/Doxyfile1297
-rw-r--r--source3/nsswitch/libwbclient/libwbclient.h46
-rw-r--r--source3/nsswitch/libwbclient/wbc_err_internal.h45
-rw-r--r--source3/nsswitch/libwbclient/wbc_guid.c104
-rw-r--r--source3/nsswitch/libwbclient/wbc_idmap.c468
-rw-r--r--source3/nsswitch/libwbclient/wbc_pam.c1034
-rw-r--r--source3/nsswitch/libwbclient/wbc_pwd.c571
-rw-r--r--source3/nsswitch/libwbclient/wbc_sid.c672
-rw-r--r--source3/nsswitch/libwbclient/wbc_util.c672
-rw-r--r--source3/nsswitch/libwbclient/wbclient.c159
-rw-r--r--source3/nsswitch/libwbclient/wbclient.h1187
-rw-r--r--source3/nsswitch/libwbclient/wbclient_internal.h32
-rw-r--r--source3/nsswitch/pam_winbind.c3204
-rw-r--r--source3/nsswitch/pam_winbind.h170
-rw-r--r--source3/nsswitch/wb_common.c690
-rw-r--r--source3/nsswitch/wbinfo.c1984
-rw-r--r--source3/nsswitch/winbind_client.h30
-rw-r--r--source3/nsswitch/winbind_krb5_locator.c411
-rw-r--r--source3/nsswitch/winbind_nss.h76
-rw-r--r--source3/nsswitch/winbind_nss_aix.c1077
-rw-r--r--source3/nsswitch/winbind_nss_config.h69
-rw-r--r--source3/nsswitch/winbind_nss_freebsd.c79
-rw-r--r--source3/nsswitch/winbind_nss_hpux.h137
-rw-r--r--source3/nsswitch/winbind_nss_irix.c633
-rw-r--r--source3/nsswitch/winbind_nss_irix.h42
-rw-r--r--source3/nsswitch/winbind_nss_linux.c1477
-rw-r--r--source3/nsswitch/winbind_nss_linux.h29
-rw-r--r--source3/nsswitch/winbind_nss_netbsd.c442
-rw-r--r--source3/nsswitch/winbind_nss_netbsd.h40
-rw-r--r--source3/nsswitch/winbind_nss_solaris.c654
-rw-r--r--source3/nsswitch/winbind_nss_solaris.h85
-rw-r--r--source3/nsswitch/winbind_struct_protocol.h516
-rw-r--r--source3/nsswitch/wins.c446
33 files changed, 0 insertions, 18578 deletions
diff --git a/source3/nsswitch/libwbclient/Doxyfile b/source3/nsswitch/libwbclient/Doxyfile
deleted file mode 100644
index e12c2b06f0..0000000000
--- a/source3/nsswitch/libwbclient/Doxyfile
+++ /dev/null
@@ -1,1297 +0,0 @@
-# Doxyfile 1.5.3
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-# TAG = value [value, ...]
-# For lists items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the config file that
-# follow. The default is UTF-8 which is also the encoding used for all text before
-# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into
-# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of
-# possible encodings.
-
-DOXYFILE_ENCODING = UTF-8
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
-# by quotes) that should identify the project.
-
-PROJECT_NAME = Samba
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
-# if some version control system is used.
-
-PROJECT_NUMBER = HEAD
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY = dox
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
-# 4096 sub-directories (in 2 levels) under the output directory of each output
-# format and will distribute the generated files over these directories.
-# Enabling this option can be useful when feeding doxygen a huge amount of
-# source files, where putting all generated files in the same directory would
-# otherwise cause performance problems for the file system.
-
-CREATE_SUBDIRS = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
-# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian,
-# Italian, Japanese, Japanese-en (Japanese with English messages), Korean,
-# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian,
-# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
-
-OUTPUT_LANGUAGE = English
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator
-# that is used to form the text in various listings. Each string
-# in this list, if found as the leading text of the brief description, will be
-# stripped from the text and the result after processing the whole list, is
-# used as the annotated text. Otherwise, the brief description is used as-is.
-# If left blank, the following values are used ("$name" is automatically
-# replaced with the name of the entity): "The $name class" "The $name widget"
-# "The $name file" "is" "provides" "specifies" "contains"
-# "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF =
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
-# description.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-
-INLINE_INHERITED_MEMB = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES = YES
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user-defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the
-# path to strip.
-
-STRIP_FROM_PATH = $(PWD)/
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
-# the path mentioned in the documentation of a class, which tells
-# the reader which header file to include in order to use a class.
-# If left blank only the name of the header file containing the class
-# definition is used. Otherwise one should specify the include paths that
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH =
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful is your file systems
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like regular Qt-style comments
-# (thus requiring an explicit @brief command for a brief description.)
-
-JAVADOC_AUTOBRIEF = YES
-
-# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
-# interpret the first line (until the first dot) of a Qt-style
-# comment as the brief description. If set to NO, the comments
-# will behave just like regular Qt-style comments (thus requiring
-# an explicit \brief command for a brief description.)
-
-QT_AUTOBRIEF = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
-# treat a multi-line C++ special comment block (i.e. a block of //! or ///
-# comments) as a brief description. This used to be the default behaviour.
-# The new default is to treat a multi-line C++ comment block as a detailed
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the DETAILS_AT_TOP tag is set to YES then Doxygen
-# will output the detailed description near the top, like JavaDoc.
-# If set to NO, the detailed description appears after the member
-# documentation.
-
-DETAILS_AT_TOP = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
-# re-implements.
-
-INHERIT_DOCS = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
-# a new page for each member. If set to NO, the documentation of a member will
-# be part of the file/class/namespace that contains it.
-
-SEPARATE_MEMBER_PAGES = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE = 8
-
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user-defined paragraph with heading "Side Effects:".
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES =
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
-# sources only. Doxygen will then generate output that is more tailored for C.
-# For instance, some of the names that are used will be different. The list
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C = YES
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
-# sources only. Doxygen will then generate output that is more tailored for Java.
-# For instance, namespaces will be presented as packages, qualified scopes
-# will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA = NO
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
-# include (a tag file for) the STL sources as input, then you should
-# set this tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
-# func(std::string) {}). This also make the inheritance and collaboration
-# diagrams that involve STL classes more complete and accurate.
-
-BUILTIN_STL_SUPPORT = NO
-
-# If you use Microsoft's C++/CLI language, you should set this option to YES to
-# enable parsing support.
-
-CPP_CLI_SUPPORT = NO
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
-# the same type (for instance a group of public functions) to be put as a
-# subgroup of that type (e.g. under the Public Functions section). Set it to
-# NO to prevent subgrouping. Alternatively, this can be done per class using
-# the \nosubgrouping command.
-
-SUBGROUPING = YES
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
-# will be included in the documentation.
-
-EXTRACT_PRIVATE = YES
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
-# will be included in the documentation.
-
-EXTRACT_STATIC = YES
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
-# defined locally in source files will be included in the documentation.
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES = YES
-
-# This flag is only useful for Objective-C code. When set to YES local
-# methods, which are defined in the implementation section but not in
-# the interface are included in the documentation.
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS = NO
-
-# If this flag is set to YES, the members of anonymous namespaces will be extracted
-# and appear in the documentation as a namespace called 'anonymous_namespace{file}',
-# where file will be replaced with the base name of the file that contains the anonymous
-# namespace. By default anonymous namespace are hidden.
-
-EXTRACT_ANON_NSPACES = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these classes will be included in the various
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
-# friend (class|struct|union) declarations.
-# If set to NO (the default) these declarations will be included in the
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
-# documentation blocks found inside the body of a function.
-# If set to NO (the default) these blocks will be appended to the
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS = NO
-
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS = YES
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower-case letters. If set to YES upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES = YES
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put a list of the files that are included by a file in the documentation
-# of that file.
-
-SHOW_INCLUDE_FILES = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
-# is inserted in the documentation for inline members.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
-# declaration order.
-
-SORT_MEMBER_DOCS = NO
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
-# brief documentation of file, namespace and class members alphabetically
-# by member name. If set to NO (the default) the members will appear in
-# declaration order.
-
-SORT_BRIEF_DOCS = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
-# sorted by fully-qualified names, including namespaces. If set to
-# NO (the default), the class list will be sorted only by class name,
-# not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
-# commands in the documentation.
-
-GENERATE_TODOLIST = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
-# commands in the documentation.
-
-GENERATE_TESTLIST = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or
-# disable (NO) the bug list. This list is created by putting \bug
-# commands in the documentation.
-
-GENERATE_BUGLIST = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
-# disable (NO) the deprecated list. This list is created by putting
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
-# the initial value of a variable or define consists of for it to appear in
-# the documentation. If the initializer consists of more lines than specified
-# here it will be hidden. Use a value of 0 to hide initializers completely.
-# The appearance of the initializer of individual variables and defines in the
-# documentation can be controlled using \showinitializer or \hideinitializer
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
-# at the bottom of the documentation of classes and structs. If set to YES the
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES = YES
-
-# If the sources in your project are distributed over multiple directories
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
-# in the documentation. The default is NO.
-
-SHOW_DIRECTORIES = NO
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from the
-# version control system). Doxygen will invoke the program by executing (via
-# popen()) the command <command> <input-file>, where <command> is the value of
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
-# provided by doxygen. Whatever the program writes to standard output
-# is used as the file version. See the manual for examples.
-
-FILE_VERSION_FILTER =
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET = YES
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
-# NO is used.
-
-WARNINGS = NO
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED = NO
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some
-# parameters in a documented function, or documenting parameters that
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR = YES
-
-# This WARN_NO_PARAMDOC option can be abled to get warnings for
-# functions that are documented, but have no documentation for their parameters
-# or return value. If set to NO (the default) doxygen will only warn about
-# wrong or incomplete parameter documentation, but not about the absence of
-# documentation.
-
-WARN_NO_PARAMDOC = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
-# warning originated and the warning text. Optionally the format may contain
-# $version, which will be replaced by the version of the file (if it could
-# be obtained via FILE_VERSION_FILTER)
-
-WARN_FORMAT = "$file:$line: $text "
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
-# to stderr.
-
-WARN_LOGFILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
-# with spaces.
-
-INPUT = .
-
-# This tag can be used to specify the character encoding of the source files that
-# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default
-# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding.
-# See http://www.gnu.org/software/libiconv for the list of possible encodings.
-
-INPUT_ENCODING = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank the following patterns are tested:
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
-# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
-
-FILE_PATTERNS = *.c \
- *.h \
- *.idl
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
-# If left blank NO is used.
-
-RECURSIVE = YES
-
-# The EXCLUDE tag can be used to specify files and/or directories that should
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE = include/includes.h \
- include/proto.h
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
-# directories that are symbolic links (a Unix filesystem feature) are excluded
-# from the input.
-
-EXCLUDE_SYMLINKS = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories. Note that the wildcards are matched
-# against the file with absolute path, so to exclude all test directories
-# for example use the pattern */test/*
-
-EXCLUDE_PATTERNS =
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
-# (namespaces, classes, functions, etc.) that should be excluded from the output.
-# The symbol name can be a fully qualified name, a word, or if the wildcard * is used,
-# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
-
-EXCLUDE_SYMBOLS =
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
-# the \include command).
-
-EXAMPLE_PATH =
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank all files are included.
-
-EXAMPLE_PATTERNS =
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude
-# commands irrespective of the value of the RECURSIVE tag.
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
-# the \image command).
-
-IMAGE_PATH =
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output. If FILTER_PATTERNS is specified, this tag will be
-# ignored.
-
-INPUT_FILTER =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis. Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match. The filters are a list of the form:
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
-# is applied to all files.
-
-FILTER_PATTERNS =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-# Note: To get rid of all source code in the generated output, make sure also
-# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH
-# then you must also enable this option. If you don't then doxygen will produce
-# a warning and turn it on anyway
-
-SOURCE_BROWSER = YES
-
-# Setting the INLINE_SOURCES tag to YES will include the body
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES = YES
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS = NO
-
-# If the REFERENCED_BY_RELATION tag is set to YES (the default)
-# then for each documented function all documented
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES (the default)
-# then for each documented function all documented entities
-# called/used by that function will be listed.
-
-REFERENCES_RELATION = YES
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
-# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
-# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
-# link to the source code. Otherwise they will link to the documentstion.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code
-# will point to the HTML generated by the htags(1) tool instead of doxygen
-# built-in source browser. The htags tool is part of GNU's global source
-# tagging system (see http://www.gnu.org/software/global/global.html). You
-# will need version 4.8.6 or higher.
-
-USE_HTAGS = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX = YES
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX = 1
-
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX =
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
-# generate HTML output.
-
-GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT = .
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard header.
-
-HTML_HEADER =
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard footer.
-
-HTML_FOOTER =
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet. Note that doxygen will try to copy
-# the style sheet file to the HTML output directory, so don't put your own
-# stylesheet in the HTML output directory as well, or it will be erased!
-
-HTML_STYLESHEET =
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS = YES
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP = NO
-
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
-# documentation will contain sections that can be hidden and shown after the
-# page has loaded. For this to work a browser that supports
-# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
-# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
-
-HTML_DYNAMIC_SECTIONS = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
-# be used to specify the file name of the resulting .chm file. You
-# can add a path in front of the file if the result should not be
-# written to the html output directory.
-
-CHM_FILE =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
-# be used to specify the location (absolute path including file name) of
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
-# controls if a separate .chi index file is generated (YES) or that
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
-# controls whether a binary table of contents is generated (YES) or a
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
-# the value YES disables it.
-
-DISABLE_INDEX = NO
-
-# This tag can be used to set the number of enum values (range [1..20])
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE = 3
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
-# probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
-# is shown.
-
-TREEVIEW_WIDTH = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
-# generate Latex output.
-
-GENERATE_LATEX = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked. If left blank `latex' will be used as the default command name.
-
-LATEX_CMD_NAME = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
-# generate index for LaTeX. If left blank `makeindex' will be used as the
-# default command name.
-
-MAKEINDEX_CMD_NAME = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, a4wide, letter, legal and
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE = a4wide
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS = YES
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
-# higher quality PDF documentation.
-
-USE_PDFLATEX = YES
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE = YES
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not
-# include the index chapters (such as File Index, Compound Index, etc.)
-# in the output.
-
-LATEX_HIDE_INDICES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimized for Word 97 and may not look very pretty with
-# other RTF readers or editors.
-
-GENERATE_RTF = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using WORD or other
-# programs which support those fields.
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assignments. You only have to provide
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE =
-
-# Set optional variables used in the generation of an rtf document.
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
-# generate man pages
-
-GENERATE_MAN = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT = man
-
-# The MAN_EXTENSION tag determines the extension that is added to
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION = .3
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
-# the code including all documentation.
-
-GENERATE_XML = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_SCHEMA =
-
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_DTD =
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
-# dump the program listings (including syntax highlighting
-# and cross-referencing information) to the XML output. Note that
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
-# generate an AutoGen Definitions (see autogen.sf.net) file
-# that captures the structure of the code including all
-# documentation. Note that this feature is still experimental
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will
-# generate a Perl module file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
-# moment.
-
-GENERATE_PERLMOD = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
-# nicely formatted so it can be parsed by a human reader. This is useful
-# if you want to understand what is going on. On the other hand, if this
-# tag is set to NO the size of the Perl module output will be much smaller
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY = YES
-
-# The names of the make variables in the generated doxyrules.make file
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
-# This is useful so different doxyrules.make files included by the same
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
-# files.
-
-ENABLE_PREPROCESSING = NO
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
-# PREDEFINED and EXPAND_AS_DEFINED tags.
-
-EXPAND_ONLY_PREDEF = NO
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
-# the preprocessor.
-
-INCLUDE_PATH =
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
-# be used.
-
-INCLUDE_FILE_PATTERNS =
-
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
-# omitted =1 is assumed. To prevent a macro definition from being
-# undefined via #undef or recursively expanded use the := operator
-# instead of the = operator.
-
-PREDEFINED =
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all function-like macros that are alone
-# on a line, have an all uppercase name, and do not end with a semicolon. Such
-# function macros are typically used for boiler-plate code, and will confuse
-# the parser if not removed.
-
-SKIP_FUNCTION_MACROS = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles.
-# Optionally an initial location of the external documentation
-# can be added for each tagfile. The format of a tag file without
-# this location is as follows:
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where "loc1" and "loc2" can be relative or absolute paths or
-# URLs. If a location is present for each tag, the installdox tool
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE =
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
-# will be listed.
-
-ALLEXTERNALS = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will
-# be listed.
-
-EXTERNAL_GROUPS = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
-# or super classes. Setting the tag to NO turns the diagrams off. Note that
-# this option is superseded by the HAVE_DOT option below. This is only a
-# fallback. It is recommended to install and use dot, since it yields more
-# powerful graphs.
-
-CLASS_DIAGRAMS = YES
-
-# You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to
-# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to
-# specify the directory where the mscgen tool resides. If left empty the tool is assumed to
-# be found in the default search path.
-
-MSCGEN_PATH =
-
-# If set to YES, the inheritance and collaboration graphs will hide
-# inheritance and usage relations if the target is undocumented
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT = NO
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH = YES
-
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for groups, showing the direct groups dependencies
-
-GROUP_GRAPHS = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-
-UML_LOOK = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
-# other documented files.
-
-INCLUDE_GRAPH = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH = YES
-
-# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will
-# generate a call dependency graph for every global function or class method.
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command.
-
-CALL_GRAPH = NO
-
-# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will
-# generate a caller dependency graph for every global function or class method.
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable caller graphs for selected
-# functions only using the \callergraph command.
-
-CALLER_GRAPH = NO
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY = YES
-
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
-# then doxygen will show the dependencies a directory has on other directories
-# in a graphical way. The dependency relations are determined by the #include
-# relations between the files in the directories.
-
-DIRECTORY_GRAPH = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-
-DOT_PATH =
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
-# \dotfile command).
-
-DOTFILE_DIRS =
-
-# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
-# nodes that will be shown in the graph. If the number of nodes in a graph
-# becomes larger than this value, doxygen will truncate the graph, which is
-# visualized by representing a node as a red box. Note that doxygen if the number
-# of direct children of the root node in a graph is already larger than
-# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note
-# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
-
-DOT_GRAPH_MAX_NODES = 50
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
-# graphs generated by dot. A depth value of 3 means that only nodes reachable
-# from the root by following a path via at most 3 edges will be shown. Nodes
-# that lay further from the root node will be omitted. Note that setting this
-# option to 1 or 2 may greatly reduce the computation time needed for large
-# code bases. Also note that the size of a graph can be further restricted by
-# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
-
-MAX_DOT_GRAPH_DEPTH = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, which results in a white background.
-# Warning: Depending on the platform used, enabling this option may lead to
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
-# read).
-
-DOT_TRANSPARENT = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10)
-# support this, this feature is disabled by default.
-
-DOT_MULTI_TARGETS = NO
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermediate dot files that are used to generate
-# the various graphs.
-
-DOT_CLEANUP = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE = NO
diff --git a/source3/nsswitch/libwbclient/libwbclient.h b/source3/nsswitch/libwbclient/libwbclient.h
deleted file mode 100644
index 74cba7e796..0000000000
--- a/source3/nsswitch/libwbclient/libwbclient.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind client API
-
- Copyright (C) Gerald (Jerry) Carter 2007
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _LIBWBCLIENT_H
-#define _LIBWBCLIENT_H
-
-/* Super header including necessary public and private header files
- for building the wbclient library. __DO NOT__ define anything
- in this file. Only include other headers. */
-
-/* Winbind headers */
-
-#include "nsswitch/winbind_nss_config.h"
-#include "nsswitch/winbind_struct_protocol.h"
-
-#include <talloc.h>
-
-/* Public headers */
-
-#include "wbclient.h"
-
-/* Private headers */
-
-#include "wbc_err_internal.h"
-#include "wbclient_internal.h"
-
-
-#endif /* _LIBWBCLIENT_H */
diff --git a/source3/nsswitch/libwbclient/wbc_err_internal.h b/source3/nsswitch/libwbclient/wbc_err_internal.h
deleted file mode 100644
index 83364b8cd9..0000000000
--- a/source3/nsswitch/libwbclient/wbc_err_internal.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind client API
-
- Copyright (C) Gerald (Jerry) Carter 2007
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _WBC_ERR_INTERNAL_H
-#define _WBC_ERR_INTERNAL_H
-
-/* Private macros */
-
-#define BAIL_ON_WBC_ERROR(x) \
- do { \
- if (!WBC_ERROR_IS_OK(x)) { \
- goto done; \
- } \
- } while(0);
-
-#define BAIL_ON_PTR_ERROR(x, status) \
- do { \
- if ((x) == NULL) { \
- status = WBC_ERR_NO_MEMORY; \
- goto done; \
- } else { \
- status = WBC_ERR_SUCCESS; \
- } \
- } while (0);
-
-
-#endif /* _WBC_ERR_INTERNAL_H */
diff --git a/source3/nsswitch/libwbclient/wbc_guid.c b/source3/nsswitch/libwbclient/wbc_guid.c
deleted file mode 100644
index c343e24351..0000000000
--- a/source3/nsswitch/libwbclient/wbc_guid.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind client API
-
- Copyright (C) Gerald (Jerry) Carter 2007
-
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* Required Headers */
-
-#include "libwbclient.h"
-
-/* Convert a binary GUID to a character string */
-wbcErr wbcGuidToString(const struct wbcGuid *guid,
- char **guid_string)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- if (!guid) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- *guid_string = talloc_asprintf(NULL,
- "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- guid->time_low, guid->time_mid,
- guid->time_hi_and_version,
- guid->clock_seq[0],
- guid->clock_seq[1],
- guid->node[0], guid->node[1],
- guid->node[2], guid->node[3],
- guid->node[4], guid->node[5]);
- BAIL_ON_PTR_ERROR((*guid_string), wbc_status);
-
- wbc_status = WBC_ERR_SUCCESS;
-
-done:
- return wbc_status;
-}
-
-/* @brief Convert a character string to a binary GUID */
-wbcErr wbcStringToGuid(const char *str,
- struct wbcGuid *guid)
-{
- uint32_t time_low;
- uint32_t time_mid, time_hi_and_version;
- uint32_t clock_seq[2];
- uint32_t node[6];
- int i;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- if (!guid) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (!str) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (11 == sscanf(str, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- &time_low, &time_mid, &time_hi_and_version,
- &clock_seq[0], &clock_seq[1],
- &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
- wbc_status = WBC_ERR_SUCCESS;
- } else if (11 == sscanf(str, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
- &time_low, &time_mid, &time_hi_and_version,
- &clock_seq[0], &clock_seq[1],
- &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
- wbc_status = WBC_ERR_SUCCESS;
- }
-
- BAIL_ON_WBC_ERROR(wbc_status);
-
- guid->time_low = time_low;
- guid->time_mid = time_mid;
- guid->time_hi_and_version = time_hi_and_version;
- guid->clock_seq[0] = clock_seq[0];
- guid->clock_seq[1] = clock_seq[1];
-
- for (i=0;i<6;i++) {
- guid->node[i] = node[i];
- }
-
- wbc_status = WBC_ERR_SUCCESS;
-
-done:
- return wbc_status;
-}
diff --git a/source3/nsswitch/libwbclient/wbc_idmap.c b/source3/nsswitch/libwbclient/wbc_idmap.c
deleted file mode 100644
index 5b2ab875f6..0000000000
--- a/source3/nsswitch/libwbclient/wbc_idmap.c
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind client API
-
- Copyright (C) Gerald (Jerry) Carter 2007
-
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* Required Headers */
-
-#include "libwbclient.h"
-
-/* Convert a Windows SID to a Unix uid, allocating an uid if needed */
-wbcErr wbcSidToUid(const struct wbcDomainSid *sid, uid_t *puid)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- char *sid_string = NULL;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- if (!sid || !puid) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- /* Initialize request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- wbc_status = wbcSidToString(sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
- wbcFreeMemory(sid_string);
-
- /* Make request */
-
- wbc_status = wbcRequestResponse(WINBINDD_SID_TO_UID,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- *puid = response.data.uid;
-
- wbc_status = WBC_ERR_SUCCESS;
-
- done:
- return wbc_status;
-}
-
-/* Convert a Windows SID to a Unix uid if there already is a mapping */
-wbcErr wbcQuerySidToUid(const struct wbcDomainSid *sid,
- uid_t *puid)
-{
- return WBC_ERR_NOT_IMPLEMENTED;
-}
-
-/* Convert a Unix uid to a Windows SID, allocating a SID if needed */
-wbcErr wbcUidToSid(uid_t uid, struct wbcDomainSid *sid)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct winbindd_request request;
- struct winbindd_response response;
-
- if (!sid) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- /* Initialize request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- request.data.uid = uid;
-
- /* Make request */
-
- wbc_status = wbcRequestResponse(WINBINDD_UID_TO_SID,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- wbc_status = wbcStringToSid(response.data.sid.sid, sid);
- BAIL_ON_WBC_ERROR(wbc_status);
-
-done:
- return wbc_status;
-}
-
-/* Convert a Unix uid to a Windows SID if there already is a mapping */
-wbcErr wbcQueryUidToSid(uid_t uid,
- struct wbcDomainSid *sid)
-{
- return WBC_ERR_NOT_IMPLEMENTED;
-}
-
-/** @brief Convert a Windows SID to a Unix gid, allocating a gid if needed
- *
- * @param *sid Pointer to the domain SID to be resolved
- * @param *pgid Pointer to the resolved gid_t value
- *
- * @return #wbcErr
- *
- **/
-
-wbcErr wbcSidToGid(const struct wbcDomainSid *sid, gid_t *pgid)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *sid_string = NULL;
-
- if (!sid || !pgid) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- /* Initialize request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- wbc_status = wbcSidToString(sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
- wbcFreeMemory(sid_string);
-
- /* Make request */
-
- wbc_status = wbcRequestResponse(WINBINDD_SID_TO_GID,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- *pgid = response.data.gid;
-
- wbc_status = WBC_ERR_SUCCESS;
-
- done:
- return wbc_status;
-}
-
-/* Convert a Windows SID to a Unix gid if there already is a mapping */
-
-wbcErr wbcQuerySidToGid(const struct wbcDomainSid *sid,
- gid_t *pgid)
-{
- return WBC_ERR_NOT_IMPLEMENTED;
-}
-
-/* Convert a Unix gid to a Windows SID, allocating a SID if needed */
-wbcErr wbcGidToSid(gid_t gid, struct wbcDomainSid *sid)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- if (!sid) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- /* Initialize request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- request.data.gid = gid;
-
- /* Make request */
-
- wbc_status = wbcRequestResponse(WINBINDD_GID_TO_SID,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- wbc_status = wbcStringToSid(response.data.sid.sid, sid);
- BAIL_ON_WBC_ERROR(wbc_status);
-
-done:
- return wbc_status;
-}
-
-/* Convert a Unix gid to a Windows SID if there already is a mapping */
-wbcErr wbcQueryGidToSid(gid_t gid,
- struct wbcDomainSid *sid)
-{
- return WBC_ERR_NOT_IMPLEMENTED;
-}
-
-/* Obtain a new uid from Winbind */
-wbcErr wbcAllocateUid(uid_t *puid)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- if (!puid)
- return WBC_ERR_INVALID_PARAM;
-
- /* Initialise request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Make request */
-
- wbc_status = wbcRequestResponse(WINBINDD_ALLOCATE_UID,
- &request, &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- /* Copy out result */
- *puid = response.data.uid;
-
- wbc_status = WBC_ERR_SUCCESS;
-
- done:
- return wbc_status;
-}
-
-/* Obtain a new gid from Winbind */
-wbcErr wbcAllocateGid(gid_t *pgid)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- if (!pgid)
- return WBC_ERR_INVALID_PARAM;
-
- /* Initialise request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Make request */
-
- wbc_status = wbcRequestResponse(WINBINDD_ALLOCATE_GID,
- &request, &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- /* Copy out result */
- *pgid = response.data.gid;
-
- wbc_status = WBC_ERR_SUCCESS;
-
- done:
- return wbc_status;
-}
-
-/* we can't include smb.h here... */
-#define _ID_TYPE_UID 1
-#define _ID_TYPE_GID 2
-
-/* Set an user id mapping */
-wbcErr wbcSetUidMapping(uid_t uid, const struct wbcDomainSid *sid)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *sid_string = NULL;
-
- if (!sid) {
- return WBC_ERR_INVALID_PARAM;
- }
-
- /* Initialise request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Make request */
-
- request.data.dual_idmapset.id = uid;
- request.data.dual_idmapset.type = _ID_TYPE_UID;
-
- wbc_status = wbcSidToString(sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.dual_idmapset.sid, sid_string,
- sizeof(request.data.dual_idmapset.sid)-1);
- wbcFreeMemory(sid_string);
-
- wbc_status = wbcRequestResponse(WINBINDD_SET_MAPPING,
- &request, &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- done:
- return wbc_status;
-}
-
-/* Set a group id mapping */
-wbcErr wbcSetGidMapping(gid_t gid, const struct wbcDomainSid *sid)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *sid_string = NULL;
-
- if (!sid) {
- return WBC_ERR_INVALID_PARAM;
- }
-
- /* Initialise request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Make request */
-
- request.data.dual_idmapset.id = gid;
- request.data.dual_idmapset.type = _ID_TYPE_GID;
-
- wbc_status = wbcSidToString(sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.dual_idmapset.sid, sid_string,
- sizeof(request.data.dual_idmapset.sid)-1);
- wbcFreeMemory(sid_string);
-
- wbc_status = wbcRequestResponse(WINBINDD_SET_MAPPING,
- &request, &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- done:
- return wbc_status;
-}
-
-/* Remove a user id mapping */
-wbcErr wbcRemoveUidMapping(uid_t uid, const struct wbcDomainSid *sid)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *sid_string = NULL;
-
- if (!sid) {
- return WBC_ERR_INVALID_PARAM;
- }
-
- /* Initialise request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Make request */
-
- request.data.dual_idmapset.id = uid;
- request.data.dual_idmapset.type = _ID_TYPE_UID;
-
- wbc_status = wbcSidToString(sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.dual_idmapset.sid, sid_string,
- sizeof(request.data.dual_idmapset.sid)-1);
- wbcFreeMemory(sid_string);
-
- wbc_status = wbcRequestResponse(WINBINDD_REMOVE_MAPPING,
- &request, &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- done:
- return wbc_status;
-}
-
-/* Remove a group id mapping */
-wbcErr wbcRemoveGidMapping(gid_t gid, const struct wbcDomainSid *sid)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *sid_string = NULL;
-
- if (!sid) {
- return WBC_ERR_INVALID_PARAM;
- }
-
- /* Initialise request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Make request */
-
- request.data.dual_idmapset.id = gid;
- request.data.dual_idmapset.type = _ID_TYPE_GID;
-
- wbc_status = wbcSidToString(sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.dual_idmapset.sid, sid_string,
- sizeof(request.data.dual_idmapset.sid)-1);
- wbcFreeMemory(sid_string);
-
- wbc_status = wbcRequestResponse(WINBINDD_REMOVE_MAPPING,
- &request, &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- done:
- return wbc_status;
-}
-
-/* Set the highwater mark for allocated uids. */
-wbcErr wbcSetUidHwm(uid_t uid_hwm)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- /* Initialise request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Make request */
-
- request.data.dual_idmapset.id = uid_hwm;
- request.data.dual_idmapset.type = _ID_TYPE_UID;
-
- wbc_status = wbcRequestResponse(WINBINDD_SET_HWM,
- &request, &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- done:
- return wbc_status;
-}
-
-/* Set the highwater mark for allocated gids. */
-wbcErr wbcSetGidHwm(gid_t gid_hwm)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- /* Initialise request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Make request */
-
- request.data.dual_idmapset.id = gid_hwm;
- request.data.dual_idmapset.type = _ID_TYPE_GID;
-
- wbc_status = wbcRequestResponse(WINBINDD_SET_HWM,
- &request, &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- done:
- return wbc_status;
-}
diff --git a/source3/nsswitch/libwbclient/wbc_pam.c b/source3/nsswitch/libwbclient/wbc_pam.c
deleted file mode 100644
index 92c6643631..0000000000
--- a/source3/nsswitch/libwbclient/wbc_pam.c
+++ /dev/null
@@ -1,1034 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind client API
-
- Copyright (C) Gerald (Jerry) Carter 2007
- Copyright (C) Guenther Deschner 2008
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* Required Headers */
-
-#include "libwbclient.h"
-
-/* Authenticate a username/password pair */
-wbcErr wbcAuthenticateUser(const char *username,
- const char *password)
-{
- wbcErr wbc_status = WBC_ERR_SUCCESS;
- struct wbcAuthUserParams params;
-
- ZERO_STRUCT(params);
-
- params.account_name = username;
- params.level = WBC_AUTH_USER_LEVEL_PLAIN;
- params.password.plaintext = password;
-
- wbc_status = wbcAuthenticateUserEx(&params, NULL, NULL);
- BAIL_ON_WBC_ERROR(wbc_status);
-
-done:
- return wbc_status;
-}
-
-static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
- const struct winbindd_response *resp,
- struct wbcAuthUserInfo **_i)
-{
- wbcErr wbc_status = WBC_ERR_SUCCESS;
- struct wbcAuthUserInfo *i;
- struct wbcDomainSid domain_sid;
- char *p;
- uint32_t sn = 0;
- uint32_t j;
-
- i = talloc(mem_ctx, struct wbcAuthUserInfo);
- BAIL_ON_PTR_ERROR(i, wbc_status);
-
- i->user_flags = resp->data.auth.info3.user_flgs;
-
- i->account_name = talloc_strdup(i, resp->data.auth.info3.user_name);
- BAIL_ON_PTR_ERROR(i->account_name, wbc_status);
- i->user_principal= NULL;
- i->full_name = talloc_strdup(i, resp->data.auth.info3.full_name);
- BAIL_ON_PTR_ERROR(i->full_name, wbc_status);
- i->domain_name = talloc_strdup(i, resp->data.auth.info3.logon_dom);
- BAIL_ON_PTR_ERROR(i->domain_name, wbc_status);
- i->dns_domain_name= NULL;
-
- i->acct_flags = resp->data.auth.info3.acct_flags;
- memcpy(i->user_session_key,
- resp->data.auth.user_session_key,
- sizeof(i->user_session_key));
- memcpy(i->lm_session_key,
- resp->data.auth.first_8_lm_hash,
- sizeof(i->lm_session_key));
-
- i->logon_count = resp->data.auth.info3.logon_count;
- i->bad_password_count = resp->data.auth.info3.bad_pw_count;
-
- i->logon_time = resp->data.auth.info3.logon_time;
- i->logoff_time = resp->data.auth.info3.logoff_time;
- i->kickoff_time = resp->data.auth.info3.kickoff_time;
- i->pass_last_set_time = resp->data.auth.info3.pass_last_set_time;
- i->pass_can_change_time = resp->data.auth.info3.pass_can_change_time;
- i->pass_must_change_time= resp->data.auth.info3.pass_must_change_time;
-
- i->logon_server = talloc_strdup(i, resp->data.auth.info3.logon_srv);
- BAIL_ON_PTR_ERROR(i->logon_server, wbc_status);
- i->logon_script = talloc_strdup(i, resp->data.auth.info3.logon_script);
- BAIL_ON_PTR_ERROR(i->logon_script, wbc_status);
- i->profile_path = talloc_strdup(i, resp->data.auth.info3.profile_path);
- BAIL_ON_PTR_ERROR(i->profile_path, wbc_status);
- i->home_directory= talloc_strdup(i, resp->data.auth.info3.home_dir);
- BAIL_ON_PTR_ERROR(i->home_directory, wbc_status);
- i->home_drive = talloc_strdup(i, resp->data.auth.info3.dir_drive);
- BAIL_ON_PTR_ERROR(i->home_drive, wbc_status);
-
- i->num_sids = 2;
- i->num_sids += resp->data.auth.info3.num_groups;
- i->num_sids += resp->data.auth.info3.num_other_sids;
-
- i->sids = talloc_array(i, struct wbcSidWithAttr, i->num_sids);
- BAIL_ON_PTR_ERROR(i->sids, wbc_status);
-
- wbc_status = wbcStringToSid(resp->data.auth.info3.dom_sid,
- &domain_sid);
- BAIL_ON_WBC_ERROR(wbc_status);
-
-#define _SID_COMPOSE(s, d, r, a) { \
- (s).sid = d; \
- if ((s).sid.num_auths < WBC_MAXSUBAUTHS) { \
- (s).sid.sub_auths[(s).sid.num_auths++] = r; \
- } else { \
- wbc_status = WBC_ERR_INVALID_SID; \
- BAIL_ON_WBC_ERROR(wbc_status); \
- } \
- (s).attributes = a; \
-} while (0)
-
- sn = 0;
- _SID_COMPOSE(i->sids[sn], domain_sid,
- resp->data.auth.info3.user_rid,
- 0);
- sn++;
- _SID_COMPOSE(i->sids[sn], domain_sid,
- resp->data.auth.info3.group_rid,
- 0);
- sn++;
-
- p = (char *)resp->extra_data.data;
- if (!p) {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- for (j=0; j < resp->data.auth.info3.num_groups; j++) {
- uint32_t rid;
- uint32_t attrs;
- int ret;
- char *s = p;
- char *e = strchr(p, '\n');
- if (!e) {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- e[0] = '\0';
- p = &e[1];
-
- ret = sscanf(s, "0x%08X:0x%08X", &rid, &attrs);
- if (ret != 2) {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- _SID_COMPOSE(i->sids[sn], domain_sid,
- rid, attrs);
- sn++;
- }
-
- for (j=0; j < resp->data.auth.info3.num_other_sids; j++) {
- uint32_t attrs;
- int ret;
- char *s = p;
- char *a;
- char *e = strchr(p, '\n');
- if (!e) {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- e[0] = '\0';
- p = &e[1];
-
- e = strchr(s, ':');
- if (!e) {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- e[0] = '\0';
- a = &e[1];
-
- ret = sscanf(a, "0x%08X",
- &attrs);
- if (ret != 1) {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- wbc_status = wbcStringToSid(s, &i->sids[sn].sid);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- i->sids[sn].attributes = attrs;
- sn++;
- }
-
- i->num_sids = sn;
-
- *_i = i;
- i = NULL;
-done:
- talloc_free(i);
- return wbc_status;
-}
-
-static wbcErr wbc_create_error_info(TALLOC_CTX *mem_ctx,
- const struct winbindd_response *resp,
- struct wbcAuthErrorInfo **_e)
-{
- wbcErr wbc_status = WBC_ERR_SUCCESS;
- struct wbcAuthErrorInfo *e;
-
- e = talloc(mem_ctx, struct wbcAuthErrorInfo);
- BAIL_ON_PTR_ERROR(e, wbc_status);
-
- e->nt_status = resp->data.auth.nt_status;
- e->pam_error = resp->data.auth.pam_error;
- e->nt_string = talloc_strdup(e, resp->data.auth.nt_status_string);
- BAIL_ON_PTR_ERROR(e->nt_string, wbc_status);
-
- e->display_string = talloc_strdup(e, resp->data.auth.error_string);
- BAIL_ON_PTR_ERROR(e->display_string, wbc_status);
-
- *_e = e;
- e = NULL;
-
-done:
- talloc_free(e);
- return wbc_status;
-}
-
-static wbcErr wbc_create_password_policy_info(TALLOC_CTX *mem_ctx,
- const struct winbindd_response *resp,
- struct wbcUserPasswordPolicyInfo **_i)
-{
- wbcErr wbc_status = WBC_ERR_SUCCESS;
- struct wbcUserPasswordPolicyInfo *i;
-
- i = talloc(mem_ctx, struct wbcUserPasswordPolicyInfo);
- BAIL_ON_PTR_ERROR(i, wbc_status);
-
- i->min_passwordage = resp->data.auth.policy.min_passwordage;
- i->min_length_password = resp->data.auth.policy.min_length_password;
- i->password_history = resp->data.auth.policy.password_history;
- i->password_properties = resp->data.auth.policy.password_properties;
- i->expire = resp->data.auth.policy.expire;
-
- *_i = i;
- i = NULL;
-
-done:
- talloc_free(i);
- return wbc_status;
-}
-
-static wbcErr wbc_create_logon_info(TALLOC_CTX *mem_ctx,
- const struct winbindd_response *resp,
- struct wbcLogonUserInfo **_i)
-{
- wbcErr wbc_status = WBC_ERR_SUCCESS;
- struct wbcLogonUserInfo *i;
-
- i = talloc_zero(mem_ctx, struct wbcLogonUserInfo);
- BAIL_ON_PTR_ERROR(i, wbc_status);
-
- wbc_status = wbc_create_auth_info(i, resp, &i->info);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- if (resp->data.auth.krb5ccname) {
- wbc_status = wbcAddNamedBlob(&i->num_blobs,
- &i->blobs,
- "krb5ccname",
- 0,
- (uint8_t *)resp->data.auth.krb5ccname,
- strlen(resp->data.auth.krb5ccname)+1);
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (resp->data.auth.unix_username) {
- wbc_status = wbcAddNamedBlob(&i->num_blobs,
- &i->blobs,
- "unix_username",
- 0,
- (uint8_t *)resp->data.auth.unix_username,
- strlen(resp->data.auth.unix_username)+1);
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- *_i = i;
- i = NULL;
-done:
- if (!WBC_ERROR_IS_OK(wbc_status) && i) {
- wbcFreeMemory(i->blobs);
- }
-
- talloc_free(i);
- return wbc_status;
-}
-
-/* Authenticate with more detailed information */
-wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params,
- struct wbcAuthUserInfo **info,
- struct wbcAuthErrorInfo **error)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- int cmd = 0;
- struct winbindd_request request;
- struct winbindd_response response;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- if (error) {
- *error = NULL;
- }
-
- if (!params) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (!params->account_name) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- /* Initialize request */
-
- switch (params->level) {
- case WBC_AUTH_USER_LEVEL_PLAIN:
- cmd = WINBINDD_PAM_AUTH;
- request.flags = WBFLAG_PAM_INFO3_TEXT |
- WBFLAG_PAM_USER_SESSION_KEY |
- WBFLAG_PAM_LMKEY;
-
- if (!params->password.plaintext) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (params->domain_name && params->domain_name[0]) {
- /* We need to get the winbind separator :-( */
- struct winbindd_response sep_response;
-
- ZERO_STRUCT(sep_response);
-
- wbc_status = wbcRequestResponse(WINBINDD_INFO,
- NULL, &sep_response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- snprintf(request.data.auth.user,
- sizeof(request.data.auth.user)-1,
- "%s%c%s",
- params->domain_name,
- sep_response.data.info.winbind_separator,
- params->account_name);
- } else {
- strncpy(request.data.auth.user,
- params->account_name,
- sizeof(request.data.auth.user)-1);
- }
-
- strncpy(request.data.auth.pass,
- params->password.plaintext,
- sizeof(request.data.auth.pass)-1);
- break;
-
- case WBC_AUTH_USER_LEVEL_HASH:
- wbc_status = WBC_ERR_NOT_IMPLEMENTED;
- BAIL_ON_WBC_ERROR(wbc_status);
- break;
-
- case WBC_AUTH_USER_LEVEL_RESPONSE:
- cmd = WINBINDD_PAM_AUTH_CRAP;
- request.flags = WBFLAG_PAM_INFO3_TEXT |
- WBFLAG_PAM_USER_SESSION_KEY |
- WBFLAG_PAM_LMKEY;
-
- if (params->password.response.lm_length &&
- !params->password.response.lm_data) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- if (params->password.response.lm_length == 0 &&
- params->password.response.lm_data) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (params->password.response.nt_length &&
- !params->password.response.nt_data) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- if (params->password.response.nt_length == 0&&
- params->password.response.nt_data) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- strncpy(request.data.auth_crap.user,
- params->account_name,
- sizeof(request.data.auth_crap.user)-1);
- if (params->domain_name) {
- strncpy(request.data.auth_crap.domain,
- params->domain_name,
- sizeof(request.data.auth_crap.domain)-1);
- }
- if (params->workstation_name) {
- strncpy(request.data.auth_crap.workstation,
- params->workstation_name,
- sizeof(request.data.auth_crap.workstation)-1);
- }
-
- request.data.auth_crap.logon_parameters =
- params->parameter_control;
-
- memcpy(request.data.auth_crap.chal,
- params->password.response.challenge,
- sizeof(request.data.auth_crap.chal));
-
- request.data.auth_crap.lm_resp_len =
- MIN(params->password.response.lm_length,
- sizeof(request.data.auth_crap.lm_resp));
- request.data.auth_crap.nt_resp_len =
- MIN(params->password.response.nt_length,
- sizeof(request.data.auth_crap.nt_resp));
- if (params->password.response.lm_data) {
- memcpy(request.data.auth_crap.lm_resp,
- params->password.response.lm_data,
- request.data.auth_crap.lm_resp_len);
- }
- if (params->password.response.nt_data) {
- memcpy(request.data.auth_crap.nt_resp,
- params->password.response.nt_data,
- request.data.auth_crap.nt_resp_len);
- }
- break;
- default:
- break;
- }
-
- if (cmd == 0) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (params->flags) {
- request.flags |= params->flags;
- }
-
- wbc_status = wbcRequestResponse(cmd,
- &request,
- &response);
- if (response.data.auth.nt_status != 0) {
- if (error) {
- wbc_status = wbc_create_error_info(NULL,
- &response,
- error);
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- wbc_status = WBC_ERR_AUTH_ERROR;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- BAIL_ON_WBC_ERROR(wbc_status);
-
- if (info) {
- wbc_status = wbc_create_auth_info(NULL,
- &response,
- info);
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
-done:
- if (response.extra_data.data)
- free(response.extra_data.data);
-
- return wbc_status;
-}
-
-/* Trigger a verification of the trust credentials of a specific domain */
-wbcErr wbcCheckTrustCredentials(const char *domain,
- struct wbcAuthErrorInfo **error)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- if (domain) {
- /*
- * the current protocol doesn't support
- * specifying a domain
- */
- wbc_status = WBC_ERR_NOT_IMPLEMENTED;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Send request */
-
- wbc_status = wbcRequestResponse(WINBINDD_CHECK_MACHACC,
- &request,
- &response);
- if (response.data.auth.nt_status != 0) {
- if (error) {
- wbc_status = wbc_create_error_info(NULL,
- &response,
- error);
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- wbc_status = WBC_ERR_AUTH_ERROR;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- BAIL_ON_WBC_ERROR(wbc_status);
-
- done:
- return wbc_status;
-}
-
-/* Trigger an extended logoff notification to Winbind for a specific user */
-wbcErr wbcLogoffUserEx(const struct wbcLogoffUserParams *params,
- struct wbcAuthErrorInfo **error)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- int i;
-
- /* validate input */
-
- if (!params || !params->username) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if ((params->num_blobs > 0) && (params->blobs == NULL)) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- if ((params->num_blobs == 0) && (params->blobs != NULL)) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- strncpy(request.data.logoff.user, params->username,
- sizeof(request.data.logoff.user)-1);
-
- for (i=0; i<params->num_blobs; i++) {
-
- if (strcasecmp(params->blobs[i].name, "ccfilename") == 0) {
- if (params->blobs[i].blob.data) {
- strncpy(request.data.logoff.krb5ccname,
- (const char *)params->blobs[i].blob.data,
- sizeof(request.data.logoff.krb5ccname) - 1);
- }
- continue;
- }
-
- if (strcasecmp(params->blobs[i].name, "user_uid") == 0) {
- if (params->blobs[i].blob.data) {
- memcpy(&request.data.logoff.uid,
- params->blobs[i].blob.data,
- MIN(params->blobs[i].blob.length,
- sizeof(request.data.logoff.uid)));
- }
- continue;
- }
-
- if (strcasecmp(params->blobs[i].name, "flags") == 0) {
- if (params->blobs[i].blob.data) {
- memcpy(&request.flags,
- params->blobs[i].blob.data,
- MIN(params->blobs[i].blob.length,
- sizeof(request.flags)));
- }
- continue;
- }
- }
-
- /* Send request */
-
- wbc_status = wbcRequestResponse(WINBINDD_PAM_LOGOFF,
- &request,
- &response);
-
- /* Take the response above and return it to the caller */
- if (response.data.auth.nt_status != 0) {
- if (error) {
- wbc_status = wbc_create_error_info(NULL,
- &response,
- error);
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- wbc_status = WBC_ERR_AUTH_ERROR;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- BAIL_ON_WBC_ERROR(wbc_status);
-
- done:
- return wbc_status;
-}
-
-/* Trigger a logoff notification to Winbind for a specific user */
-wbcErr wbcLogoffUser(const char *username,
- uid_t uid,
- const char *ccfilename)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- /* validate input */
-
- if (!username) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- strncpy(request.data.logoff.user, username,
- sizeof(request.data.logoff.user)-1);
- request.data.logoff.uid = uid;
-
- if (ccfilename) {
- strncpy(request.data.logoff.krb5ccname, ccfilename,
- sizeof(request.data.logoff.krb5ccname)-1);
- }
-
- /* Send request */
-
- wbc_status = wbcRequestResponse(WINBINDD_PAM_LOGOFF,
- &request,
- &response);
-
- /* Take the response above and return it to the caller */
-
- done:
- return wbc_status;
-}
-
-/* Change a password for a user with more detailed information upon failure */
-wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params,
- struct wbcAuthErrorInfo **error,
- enum wbcPasswordChangeRejectReason *reject_reason,
- struct wbcUserPasswordPolicyInfo **policy)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- int cmd = 0;
-
- /* validate input */
-
- if (!params->account_name) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (error) {
- *error = NULL;
- }
-
- if (policy) {
- *policy = NULL;
- }
-
- if (reject_reason) {
- *reject_reason = -1;
- }
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- switch (params->level) {
- case WBC_CHANGE_PASSWORD_LEVEL_PLAIN:
- cmd = WINBINDD_PAM_CHAUTHTOK;
-
- if (!params->account_name) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- strncpy(request.data.chauthtok.user, params->account_name,
- sizeof(request.data.chauthtok.user) - 1);
-
- if (params->old_password.plaintext) {
- strncpy(request.data.chauthtok.oldpass,
- params->old_password.plaintext,
- sizeof(request.data.chauthtok.oldpass) - 1);
- }
-
- if (params->new_password.plaintext) {
- strncpy(request.data.chauthtok.newpass,
- params->new_password.plaintext,
- sizeof(request.data.chauthtok.newpass) - 1);
- }
- break;
-
- case WBC_CHANGE_PASSWORD_LEVEL_RESPONSE:
- cmd = WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP;
-
- if (!params->account_name || !params->domain_name) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (params->old_password.response.old_lm_hash_enc_length &&
- !params->old_password.response.old_lm_hash_enc_data) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (params->old_password.response.old_lm_hash_enc_length == 0 &&
- params->old_password.response.old_lm_hash_enc_data) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (params->old_password.response.old_nt_hash_enc_length &&
- !params->old_password.response.old_nt_hash_enc_data) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (params->old_password.response.old_nt_hash_enc_length == 0 &&
- params->old_password.response.old_nt_hash_enc_data) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (params->new_password.response.lm_length &&
- !params->new_password.response.lm_data) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (params->new_password.response.lm_length == 0 &&
- params->new_password.response.lm_data) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (params->new_password.response.nt_length &&
- !params->new_password.response.nt_data) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (params->new_password.response.nt_length == 0 &&
- params->new_password.response.nt_data) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- strncpy(request.data.chng_pswd_auth_crap.user,
- params->account_name,
- sizeof(request.data.chng_pswd_auth_crap.user) - 1);
-
- strncpy(request.data.chng_pswd_auth_crap.domain,
- params->domain_name,
- sizeof(request.data.chng_pswd_auth_crap.domain) - 1);
-
- if (params->new_password.response.nt_data) {
- memcpy(request.data.chng_pswd_auth_crap.new_nt_pswd,
- params->new_password.response.nt_data,
- request.data.chng_pswd_auth_crap.new_nt_pswd_len);
- request.data.chng_pswd_auth_crap.new_nt_pswd_len =
- params->new_password.response.nt_length;
- }
-
- if (params->new_password.response.lm_data) {
- memcpy(request.data.chng_pswd_auth_crap.new_lm_pswd,
- params->new_password.response.lm_data,
- request.data.chng_pswd_auth_crap.new_lm_pswd_len);
- request.data.chng_pswd_auth_crap.new_lm_pswd_len =
- params->new_password.response.lm_length;
- }
-
- if (params->old_password.response.old_nt_hash_enc_data) {
- memcpy(request.data.chng_pswd_auth_crap.old_nt_hash_enc,
- params->old_password.response.old_nt_hash_enc_data,
- request.data.chng_pswd_auth_crap.old_nt_hash_enc_len);
- request.data.chng_pswd_auth_crap.old_nt_hash_enc_len =
- params->old_password.response.old_nt_hash_enc_length;
- }
-
- if (params->old_password.response.old_lm_hash_enc_data) {
- memcpy(request.data.chng_pswd_auth_crap.old_lm_hash_enc,
- params->old_password.response.old_lm_hash_enc_data,
- request.data.chng_pswd_auth_crap.old_lm_hash_enc_len);
- request.data.chng_pswd_auth_crap.old_lm_hash_enc_len =
- params->old_password.response.old_lm_hash_enc_length;
- }
-
- break;
- default:
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- break;
- }
-
- if (cmd == 0) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- /* Send request */
-
- wbc_status = wbcRequestResponse(cmd,
- &request,
- &response);
- if (WBC_ERROR_IS_OK(wbc_status)) {
- goto done;
- }
-
- /* Take the response above and return it to the caller */
-
- if (response.data.auth.nt_status != 0) {
- if (error) {
- wbc_status = wbc_create_error_info(NULL,
- &response,
- error);
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- }
-
- if (policy) {
- wbc_status = wbc_create_password_policy_info(NULL,
- &response,
- policy);
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (reject_reason) {
- *reject_reason = response.data.auth.reject_reason;
- }
-
- wbc_status = WBC_ERR_PWD_CHANGE_FAILED;
- BAIL_ON_WBC_ERROR(wbc_status);
-
- done:
- return wbc_status;
-}
-
-/* Change a password for a user */
-wbcErr wbcChangeUserPassword(const char *username,
- const char *old_password,
- const char *new_password)
-{
- wbcErr wbc_status = WBC_ERR_SUCCESS;
- struct wbcChangePasswordParams params;
-
- ZERO_STRUCT(params);
-
- params.account_name = username;
- params.level = WBC_CHANGE_PASSWORD_LEVEL_PLAIN;
- params.old_password.plaintext = old_password;
- params.new_password.plaintext = new_password;
-
- wbc_status = wbcChangeUserPasswordEx(&params,
- NULL,
- NULL,
- NULL);
- BAIL_ON_WBC_ERROR(wbc_status);
-
-done:
- return wbc_status;
-}
-
-/* Logon a User */
-wbcErr wbcLogonUser(const struct wbcLogonUserParams *params,
- struct wbcLogonUserInfo **info,
- struct wbcAuthErrorInfo **error,
- struct wbcUserPasswordPolicyInfo **policy)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- int cmd = 0;
- struct winbindd_request request;
- struct winbindd_response response;
- uint32_t i;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- if (info) {
- *info = NULL;
- }
- if (error) {
- *error = NULL;
- }
- if (policy) {
- *policy = NULL;
- }
-
- if (!params) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (!params->username) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if ((params->num_blobs > 0) && (params->blobs == NULL)) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- if ((params->num_blobs == 0) && (params->blobs != NULL)) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- /* Initialize request */
-
- cmd = WINBINDD_PAM_AUTH;
- request.flags = WBFLAG_PAM_INFO3_TEXT |
- WBFLAG_PAM_USER_SESSION_KEY |
- WBFLAG_PAM_LMKEY;
-
- if (!params->password) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- strncpy(request.data.auth.user,
- params->username,
- sizeof(request.data.auth.user)-1);
-
- strncpy(request.data.auth.pass,
- params->password,
- sizeof(request.data.auth.pass)-1);
-
- for (i=0; i<params->num_blobs; i++) {
-
- if (strcasecmp(params->blobs[i].name, "krb5_cc_type") == 0) {
- if (params->blobs[i].blob.data) {
- strncpy(request.data.auth.krb5_cc_type,
- (const char *)params->blobs[i].blob.data,
- sizeof(request.data.auth.krb5_cc_type) - 1);
- }
- continue;
- }
-
- if (strcasecmp(params->blobs[i].name, "user_uid") == 0) {
- if (params->blobs[i].blob.data) {
- memcpy(&request.data.auth.uid,
- params->blobs[i].blob.data,
- MIN(sizeof(request.data.auth.uid),
- params->blobs[i].blob.length));
- }
- continue;
- }
-
- if (strcasecmp(params->blobs[i].name, "flags") == 0) {
- if (params->blobs[i].blob.data) {
- uint32_t flags;
- memcpy(&flags,
- params->blobs[i].blob.data,
- MIN(sizeof(flags),
- params->blobs[i].blob.length));
- request.flags |= flags;
- }
- continue;
- }
-
- if (strcasecmp(params->blobs[i].name, "membership_of") == 0) {
- if (params->blobs[i].blob.data &&
- params->blobs[i].blob.data[0] > 0) {
- strncpy(request.data.auth.require_membership_of_sid,
- (const char *)params->blobs[i].blob.data,
- sizeof(request.data.auth.require_membership_of_sid) - 1);
- }
- continue;
- }
- }
-
- wbc_status = wbcRequestResponse(cmd,
- &request,
- &response);
-
- if (response.data.auth.nt_status != 0) {
- if (error) {
- wbc_status = wbc_create_error_info(NULL,
- &response,
- error);
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- wbc_status = WBC_ERR_AUTH_ERROR;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- BAIL_ON_WBC_ERROR(wbc_status);
-
- if (info) {
- wbc_status = wbc_create_logon_info(NULL,
- &response,
- info);
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (policy) {
- wbc_status = wbc_create_password_policy_info(NULL,
- &response,
- policy);
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
-done:
- if (response.extra_data.data)
- free(response.extra_data.data);
-
- return wbc_status;
-}
-
-/* Authenticate a user with cached credentials */
-wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params,
- struct wbcCredentialCacheInfo **info,
- struct wbcAuthErrorInfo **error)
-{
- return WBC_ERR_NOT_IMPLEMENTED;
-}
diff --git a/source3/nsswitch/libwbclient/wbc_pwd.c b/source3/nsswitch/libwbclient/wbc_pwd.c
deleted file mode 100644
index cd945996c8..0000000000
--- a/source3/nsswitch/libwbclient/wbc_pwd.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind client API
-
- Copyright (C) Gerald (Jerry) Carter 2007
-
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* Required Headers */
-
-#include "libwbclient.h"
-
-/** @brief The maximum number of pwent structs to get from winbindd
- *
- */
-#define MAX_GETPWENT_USERS 500
-
-/** @brief The maximum number of grent structs to get from winbindd
- *
- */
-#define MAX_GETGRENT_GROUPS 500
-
-/**
- *
- **/
-
-static struct passwd *copy_passwd_entry(struct winbindd_pw *p)
-{
- struct passwd *pwd = NULL;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- pwd = talloc(NULL, struct passwd);
- BAIL_ON_PTR_ERROR(pwd, wbc_status);
-
- pwd->pw_name = talloc_strdup(pwd,p->pw_name);
- BAIL_ON_PTR_ERROR(pwd->pw_name, wbc_status);
-
- pwd->pw_passwd = talloc_strdup(pwd, p->pw_passwd);
- BAIL_ON_PTR_ERROR(pwd->pw_passwd, wbc_status);
-
- pwd->pw_gecos = talloc_strdup(pwd, p->pw_gecos);
- BAIL_ON_PTR_ERROR(pwd->pw_gecos, wbc_status);
-
- pwd->pw_shell = talloc_strdup(pwd, p->pw_shell);
- BAIL_ON_PTR_ERROR(pwd->pw_shell, wbc_status);
-
- pwd->pw_dir = talloc_strdup(pwd, p->pw_dir);
- BAIL_ON_PTR_ERROR(pwd->pw_dir, wbc_status);
-
- pwd->pw_uid = p->pw_uid;
- pwd->pw_gid = p->pw_gid;
-
-done:
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- talloc_free(pwd);
- pwd = NULL;
- }
-
- return pwd;
-}
-
-/**
- *
- **/
-
-static struct group *copy_group_entry(struct winbindd_gr *g,
- char *mem_buf)
-{
- struct group *grp = NULL;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- int i;
- char *mem_p, *mem_q;
-
- grp = talloc(NULL, struct group);
- BAIL_ON_PTR_ERROR(grp, wbc_status);
-
- grp->gr_name = talloc_strdup(grp, g->gr_name);
- BAIL_ON_PTR_ERROR(grp->gr_name, wbc_status);
-
- grp->gr_passwd = talloc_strdup(grp, g->gr_passwd);
- BAIL_ON_PTR_ERROR(grp->gr_passwd, wbc_status);
-
- grp->gr_gid = g->gr_gid;
-
- grp->gr_mem = talloc_array(grp, char*, g->num_gr_mem+1);
-
- mem_p = mem_q = mem_buf;
- for (i=0; i<g->num_gr_mem && mem_p; i++) {
- if ((mem_q = strchr(mem_p, ',')) != NULL) {
- *mem_q = '\0';
- }
-
- grp->gr_mem[i] = talloc_strdup(grp, mem_p);
- BAIL_ON_PTR_ERROR(grp->gr_mem[i], wbc_status);
-
- if (mem_q == NULL) {
- i += 1;
- break;
- }
- mem_p = mem_q + 1;
- }
- grp->gr_mem[i] = NULL;
-
- wbc_status = WBC_ERR_SUCCESS;
-
-done:
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- talloc_free(grp);
- grp = NULL;
- }
-
- return grp;
-}
-
-/* Fill in a struct passwd* for a domain user based on username */
-wbcErr wbcGetpwnam(const char *name, struct passwd **pwd)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct winbindd_request request;
- struct winbindd_response response;
-
- if (!name || !pwd) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- /* Initialize request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* dst is already null terminated from the memset above */
-
- strncpy(request.data.username, name, sizeof(request.data.username)-1);
-
- wbc_status = wbcRequestResponse(WINBINDD_GETPWNAM,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- *pwd = copy_passwd_entry(&response.data.pw);
- BAIL_ON_PTR_ERROR(*pwd, wbc_status);
-
- done:
- return wbc_status;
-}
-
-/* Fill in a struct passwd* for a domain user based on uid */
-wbcErr wbcGetpwuid(uid_t uid, struct passwd **pwd)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct winbindd_request request;
- struct winbindd_response response;
-
- if (!pwd) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- /* Initialize request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- request.data.uid = uid;
-
- wbc_status = wbcRequestResponse(WINBINDD_GETPWUID,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- *pwd = copy_passwd_entry(&response.data.pw);
- BAIL_ON_PTR_ERROR(*pwd, wbc_status);
-
- done:
- return wbc_status;
-}
-
-/* Fill in a struct passwd* for a domain user based on username */
-wbcErr wbcGetgrnam(const char *name, struct group **grp)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct winbindd_request request;
- struct winbindd_response response;
-
- /* Initialize request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- if (!name || !grp) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- /* dst is already null terminated from the memset above */
-
- strncpy(request.data.groupname, name, sizeof(request.data.groupname)-1);
-
- wbc_status = wbcRequestResponse(WINBINDD_GETGRNAM,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- *grp = copy_group_entry(&response.data.gr,
- (char*)response.extra_data.data);
- BAIL_ON_PTR_ERROR(*grp, wbc_status);
-
- done:
- if (response.extra_data.data)
- free(response.extra_data.data);
-
- return wbc_status;
-}
-
-/* Fill in a struct passwd* for a domain user based on uid */
-wbcErr wbcGetgrgid(gid_t gid, struct group **grp)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct winbindd_request request;
- struct winbindd_response response;
-
- /* Initialize request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- if (!grp) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- request.data.gid = gid;
-
- wbc_status = wbcRequestResponse(WINBINDD_GETGRGID,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- *grp = copy_group_entry(&response.data.gr,
- (char*)response.extra_data.data);
- BAIL_ON_PTR_ERROR(*grp, wbc_status);
-
- done:
- if (response.extra_data.data)
- free(response.extra_data.data);
-
- return wbc_status;
-}
-
-/** @brief Number of cached passwd structs
- *
- */
-static uint32_t pw_cache_size;
-
-/** @brief Position of the pwent context
- *
- */
-static uint32_t pw_cache_idx;
-
-/** @brief Winbindd response containing the passwd structs
- *
- */
-static struct winbindd_response pw_response;
-
-/* Reset the passwd iterator */
-wbcErr wbcSetpwent(void)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- if (pw_cache_size > 0) {
- pw_cache_idx = pw_cache_size = 0;
- if (pw_response.extra_data.data) {
- free(pw_response.extra_data.data);
- }
- }
-
- ZERO_STRUCT(pw_response);
-
- wbc_status = wbcRequestResponse(WINBINDD_SETPWENT,
- NULL, NULL);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- done:
- return wbc_status;
-}
-
-/* Close the passwd iterator */
-wbcErr wbcEndpwent(void)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- if (pw_cache_size > 0) {
- pw_cache_idx = pw_cache_size = 0;
- if (pw_response.extra_data.data) {
- free(pw_response.extra_data.data);
- }
- }
-
- wbc_status = wbcRequestResponse(WINBINDD_ENDPWENT,
- NULL, NULL);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- done:
- return wbc_status;
-}
-
-/* Return the next struct passwd* entry from the pwent iterator */
-wbcErr wbcGetpwent(struct passwd **pwd)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct winbindd_request request;
- struct winbindd_pw *wb_pw;
-
- /* If there's a cached result, return that. */
- if (pw_cache_idx < pw_cache_size) {
- goto return_result;
- }
-
- /* Otherwise, query winbindd for some entries. */
-
- pw_cache_idx = 0;
-
- if (pw_response.extra_data.data) {
- free(pw_response.extra_data.data);
- ZERO_STRUCT(pw_response);
- }
-
- ZERO_STRUCT(request);
- request.data.num_entries = MAX_GETPWENT_USERS;
-
- wbc_status = wbcRequestResponse(WINBINDD_GETPWENT, &request,
- &pw_response);
-
- BAIL_ON_WBC_ERROR(wbc_status);
-
- pw_cache_size = pw_response.data.num_entries;
-
-return_result:
-
- wb_pw = (struct winbindd_pw *) pw_response.extra_data.data;
-
- *pwd = copy_passwd_entry(&wb_pw[pw_cache_idx]);
-
- BAIL_ON_PTR_ERROR(*pwd, wbc_status);
-
- pw_cache_idx++;
-
-done:
- return wbc_status;
-}
-
-/** @brief Number of cached group structs
- *
- */
-static uint32_t gr_cache_size;
-
-/** @brief Position of the grent context
- *
- */
-static uint32_t gr_cache_idx;
-
-/** @brief Winbindd response containing the group structs
- *
- */
-static struct winbindd_response gr_response;
-
-/* Reset the group iterator */
-wbcErr wbcSetgrent(void)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- if (gr_cache_size > 0) {
- gr_cache_idx = gr_cache_size = 0;
- if (gr_response.extra_data.data) {
- free(gr_response.extra_data.data);
- }
- }
-
- ZERO_STRUCT(gr_response);
-
- wbc_status = wbcRequestResponse(WINBINDD_SETGRENT,
- NULL, NULL);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- done:
- return wbc_status;
-}
-
-/* Close the group iterator */
-wbcErr wbcEndgrent(void)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- if (gr_cache_size > 0) {
- gr_cache_idx = gr_cache_size = 0;
- if (gr_response.extra_data.data) {
- free(gr_response.extra_data.data);
- }
- }
-
- wbc_status = wbcRequestResponse(WINBINDD_ENDGRENT,
- NULL, NULL);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- done:
- return wbc_status;
-}
-
-/* Return the next struct group* entry from the pwent iterator */
-wbcErr wbcGetgrent(struct group **grp)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct winbindd_request request;
- struct winbindd_gr *wb_gr;
- uint32_t mem_ofs;
-
- /* If there's a cached result, return that. */
- if (gr_cache_idx < gr_cache_size) {
- goto return_result;
- }
-
- /* Otherwise, query winbindd for some entries. */
-
- gr_cache_idx = 0;
-
- if (gr_response.extra_data.data) {
- free(gr_response.extra_data.data);
- ZERO_STRUCT(gr_response);
- }
-
- ZERO_STRUCT(request);
- request.data.num_entries = MAX_GETGRENT_GROUPS;
-
- wbc_status = wbcRequestResponse(WINBINDD_GETGRENT, &request,
- &gr_response);
-
- BAIL_ON_WBC_ERROR(wbc_status);
-
- gr_cache_size = gr_response.data.num_entries;
-
-return_result:
-
- wb_gr = (struct winbindd_gr *) gr_response.extra_data.data;
-
- mem_ofs = wb_gr[gr_cache_idx].gr_mem_ofs +
- gr_cache_size * sizeof(struct winbindd_gr);
-
- *grp = copy_group_entry(&wb_gr[gr_cache_idx],
- ((char *)gr_response.extra_data.data)+mem_ofs);
-
- BAIL_ON_PTR_ERROR(*grp, wbc_status);
-
- gr_cache_idx++;
-
-done:
- return wbc_status;
-}
-
-/* Return the next struct group* entry from the pwent iterator */
-wbcErr wbcGetgrlist(struct group **grp)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct winbindd_request request;
- struct winbindd_gr *wb_gr;
-
- /* If there's a cached result, return that. */
- if (gr_cache_idx < gr_cache_size) {
- goto return_result;
- }
-
- /* Otherwise, query winbindd for some entries. */
-
- gr_cache_idx = 0;
-
- if (gr_response.extra_data.data) {
- free(gr_response.extra_data.data);
- ZERO_STRUCT(gr_response);
- }
-
- ZERO_STRUCT(request);
- request.data.num_entries = MAX_GETGRENT_GROUPS;
-
- wbc_status = wbcRequestResponse(WINBINDD_GETGRLST, &request,
- &gr_response);
-
- BAIL_ON_WBC_ERROR(wbc_status);
-
- gr_cache_size = gr_response.data.num_entries;
-
-return_result:
-
- wb_gr = (struct winbindd_gr *) gr_response.extra_data.data;
-
- *grp = copy_group_entry(&wb_gr[gr_cache_idx], NULL);
-
- BAIL_ON_PTR_ERROR(*grp, wbc_status);
-
- gr_cache_idx++;
-
-done:
- return wbc_status;
-}
-
-/* Return the unix group array belonging to the given user */
-wbcErr wbcGetGroups(const char *account,
- uint32_t *num_groups,
- gid_t **_groups)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct winbindd_request request;
- struct winbindd_response response;
- uint32_t i;
- gid_t *groups = NULL;
-
- /* Initialize request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- if (!account) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- /* Send request */
-
- strncpy(request.data.username, account, sizeof(request.data.username)-1);
-
- wbc_status = wbcRequestResponse(WINBINDD_GETGROUPS,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- groups = talloc_array(NULL, gid_t, response.data.num_entries);
- BAIL_ON_PTR_ERROR(groups, wbc_status);
-
- for (i = 0; i < response.data.num_entries; i++) {
- groups[i] = ((gid_t *)response.extra_data.data)[i];
- }
-
- *num_groups = response.data.num_entries;
- *_groups = groups;
- groups = NULL;
-
- wbc_status = WBC_ERR_SUCCESS;
-
- done:
- if (response.extra_data.data) {
- free(response.extra_data.data);
- }
- if (groups) {
- talloc_free(groups);
- }
-
- return wbc_status;
-}
diff --git a/source3/nsswitch/libwbclient/wbc_sid.c b/source3/nsswitch/libwbclient/wbc_sid.c
deleted file mode 100644
index e2157b9609..0000000000
--- a/source3/nsswitch/libwbclient/wbc_sid.c
+++ /dev/null
@@ -1,672 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind client API
-
- Copyright (C) Gerald (Jerry) Carter 2007
-
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* Required Headers */
-
-#include "libwbclient.h"
-
-
-/* Convert a binary SID to a character string */
-wbcErr wbcSidToString(const struct wbcDomainSid *sid,
- char **sid_string)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- uint32_t id_auth;
- int i;
- char *tmp = NULL;
-
- if (!sid) {
- wbc_status = WBC_ERR_INVALID_SID;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- id_auth = sid->id_auth[5] +
- (sid->id_auth[4] << 8) +
- (sid->id_auth[3] << 16) +
- (sid->id_auth[2] << 24);
-
- tmp = talloc_asprintf(NULL, "S-%d-%d", sid->sid_rev_num, id_auth);
- BAIL_ON_PTR_ERROR(tmp, wbc_status);
-
- for (i=0; i<sid->num_auths; i++) {
- char *tmp2;
- tmp2 = talloc_asprintf_append(tmp, "-%u", sid->sub_auths[i]);
- BAIL_ON_PTR_ERROR(tmp2, wbc_status);
-
- tmp = tmp2;
- }
-
- *sid_string = tmp;
- tmp = NULL;
-
- wbc_status = WBC_ERR_SUCCESS;
-
-done:
- talloc_free(tmp);
-
- return wbc_status;
-}
-
-/* Convert a character string to a binary SID */
-wbcErr wbcStringToSid(const char *str,
- struct wbcDomainSid *sid)
-{
- const char *p;
- char *q;
- uint32_t x;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- if (!sid) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- /* Sanity check for either "S-" or "s-" */
-
- if (!str
- || (str[0]!='S' && str[0]!='s')
- || (str[1]!='-'))
- {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- /* Get the SID revision number */
-
- p = str+2;
- x = (uint32_t)strtol(p, &q, 10);
- if (x==0 || !q || *q!='-') {
- wbc_status = WBC_ERR_INVALID_SID;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- sid->sid_rev_num = (uint8_t)x;
-
- /* Next the Identifier Authority. This is stored in big-endian
- in a 6 byte array. */
-
- p = q+1;
- x = (uint32_t)strtol(p, &q, 10);
- if (!q || *q!='-') {
- wbc_status = WBC_ERR_INVALID_SID;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- sid->id_auth[5] = (x & 0x000000ff);
- sid->id_auth[4] = (x & 0x0000ff00) >> 8;
- sid->id_auth[3] = (x & 0x00ff0000) >> 16;
- sid->id_auth[2] = (x & 0xff000000) >> 24;
- sid->id_auth[1] = 0;
- sid->id_auth[0] = 0;
-
- /* now read the the subauthorities */
-
- p = q +1;
- sid->num_auths = 0;
- while (sid->num_auths < WBC_MAXSUBAUTHS) {
- x=(uint32_t)strtoul(p, &q, 10);
- if (p == q)
- break;
- if (q == NULL) {
- wbc_status = WBC_ERR_INVALID_SID;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- sid->sub_auths[sid->num_auths++] = x;
-
- if ((*q!='-') || (*q=='\0'))
- break;
- p = q + 1;
- }
-
- /* IF we ended early, then the SID could not be converted */
-
- if (q && *q!='\0') {
- wbc_status = WBC_ERR_INVALID_SID;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- wbc_status = WBC_ERR_SUCCESS;
-
-done:
- return wbc_status;
-
-}
-
-/* Convert a domain and name to SID */
-wbcErr wbcLookupName(const char *domain,
- const char *name,
- struct wbcDomainSid *sid,
- enum wbcSidType *name_type)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- if (!sid || !name_type) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- /* Initialize request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* dst is already null terminated from the memset above */
-
- strncpy(request.data.name.dom_name, domain,
- sizeof(request.data.name.dom_name)-1);
- strncpy(request.data.name.name, name,
- sizeof(request.data.name.name)-1);
-
- wbc_status = wbcRequestResponse(WINBINDD_LOOKUPNAME,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- wbc_status = wbcStringToSid(response.data.sid.sid, sid);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- *name_type = (enum wbcSidType)response.data.sid.type;
-
- wbc_status = WBC_ERR_SUCCESS;
-
- done:
- return wbc_status;
-}
-
-/* Convert a SID to a domain and name */
-wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
- char **pdomain,
- char **pname,
- enum wbcSidType *pname_type)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *sid_string = NULL;
- char *domain = NULL;
- char *name = NULL;
- enum wbcSidType name_type = WBC_SID_NAME_USE_NONE;
-
- if (!sid) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- /* Initialize request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* dst is already null terminated from the memset above */
-
- wbc_status = wbcSidToString(sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
- wbcFreeMemory(sid_string);
-
- /* Make request */
-
- wbc_status = wbcRequestResponse(WINBINDD_LOOKUPSID,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- /* Copy out result */
-
- domain = talloc_strdup(NULL, response.data.name.dom_name);
- BAIL_ON_PTR_ERROR(domain, wbc_status);
-
- name = talloc_strdup(NULL, response.data.name.name);
- BAIL_ON_PTR_ERROR(name, wbc_status);
-
- name_type = (enum wbcSidType)response.data.name.type;
-
- wbc_status = WBC_ERR_SUCCESS;
-
- done:
- if (WBC_ERROR_IS_OK(wbc_status)) {
- if (pdomain != NULL) {
- *pdomain = domain;
- }
- if (pname != NULL) {
- *pname = name;
- }
- if (pname_type != NULL) {
- *pname_type = name_type;
- }
- }
- else {
-#if 0
- /*
- * Found by Coverity: In this particular routine we can't end
- * up here with a non-NULL name. Further up there are just two
- * exit paths that lead here, neither of which leave an
- * allocated name. If you add more paths up there, re-activate
- * this.
- */
- if (name != NULL) {
- talloc_free(name);
- }
-#endif
- if (domain != NULL) {
- talloc_free(domain);
- }
- }
-
- return wbc_status;
-}
-
-/* Translate a collection of RIDs within a domain to names */
-
-wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
- int num_rids,
- uint32_t *rids,
- const char **pp_domain_name,
- const char ***pnames,
- enum wbcSidType **ptypes)
-{
- size_t i, len, ridbuf_size;
- char *ridlist;
- char *p;
- struct winbindd_request request;
- struct winbindd_response response;
- char *sid_string = NULL;
- char *domain_name = NULL;
- const char **names = NULL;
- enum wbcSidType *types = NULL;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- /* Initialise request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- if (!dom_sid || (num_rids == 0)) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- wbc_status = wbcSidToString(dom_sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
- wbcFreeMemory(sid_string);
-
- /* Even if all the Rids were of maximum 32bit values,
- we would only have 11 bytes per rid in the final array
- ("4294967296" + \n). Add one more byte for the
- terminating '\0' */
-
- ridbuf_size = (sizeof(char)*11) * num_rids + 1;
-
- ridlist = talloc_zero_array(NULL, char, ridbuf_size);
- BAIL_ON_PTR_ERROR(ridlist, wbc_status);
-
- len = 0;
- for (i=0; i<num_rids && (len-1)>0; i++) {
- char ridstr[12];
-
- len = strlen(ridlist);
- p = ridlist + len;
-
- snprintf( ridstr, sizeof(ridstr)-1, "%u\n", rids[i]);
- strncat(p, ridstr, ridbuf_size-len-1);
- }
-
- request.extra_data.data = ridlist;
- request.extra_len = strlen(ridlist)+1;
-
- wbc_status = wbcRequestResponse(WINBINDD_LOOKUPRIDS,
- &request,
- &response);
- talloc_free(ridlist);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- domain_name = talloc_strdup(NULL, response.data.domain_name);
- BAIL_ON_PTR_ERROR(domain_name, wbc_status);
-
- names = talloc_array(NULL, const char*, num_rids);
- BAIL_ON_PTR_ERROR(names, wbc_status);
-
- types = talloc_array(NULL, enum wbcSidType, num_rids);
- BAIL_ON_PTR_ERROR(types, wbc_status);
-
- p = (char *)response.extra_data.data;
-
- for (i=0; i<num_rids; i++) {
- char *q;
-
- if (*p == '\0') {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- types[i] = (enum wbcSidType)strtoul(p, &q, 10);
-
- if (*q != ' ') {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- p = q+1;
-
- if ((q = strchr(p, '\n')) == NULL) {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- *q = '\0';
-
- names[i] = talloc_strdup(names, p);
- BAIL_ON_PTR_ERROR(names[i], wbc_status);
-
- p = q+1;
- }
-
- if (*p != '\0') {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- wbc_status = WBC_ERR_SUCCESS;
-
- done:
- if (response.extra_data.data) {
- free(response.extra_data.data);
- }
-
- if (WBC_ERROR_IS_OK(wbc_status)) {
- *pp_domain_name = domain_name;
- *pnames = names;
- *ptypes = types;
- }
- else {
- if (domain_name)
- talloc_free(domain_name);
- if (names)
- talloc_free(names);
- if (types)
- talloc_free(types);
- }
-
- return wbc_status;
-}
-
-/* Get the groups a user belongs to */
-wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid,
- bool domain_groups_only,
- uint32_t *num_sids,
- struct wbcDomainSid **_sids)
-{
- uint32_t i;
- const char *s;
- struct winbindd_request request;
- struct winbindd_response response;
- char *sid_string = NULL;
- struct wbcDomainSid *sids = NULL;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- int cmd;
-
- /* Initialise request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- if (!user_sid) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- wbc_status = wbcSidToString(user_sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
- wbcFreeMemory(sid_string);
-
- if (domain_groups_only) {
- cmd = WINBINDD_GETUSERDOMGROUPS;
- } else {
- cmd = WINBINDD_GETUSERSIDS;
- }
-
- wbc_status = wbcRequestResponse(cmd,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- if (response.data.num_entries &&
- !response.extra_data.data) {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- sids = talloc_array(NULL, struct wbcDomainSid,
- response.data.num_entries);
- BAIL_ON_PTR_ERROR(sids, wbc_status);
-
- s = (const char *)response.extra_data.data;
- for (i = 0; i < response.data.num_entries; i++) {
- char *n = strchr(s, '\n');
- if (n) {
- *n = '\0';
- }
- wbc_status = wbcStringToSid(s, &sids[i]);
- BAIL_ON_WBC_ERROR(wbc_status);
- s += strlen(s) + 1;
- }
-
- *num_sids = response.data.num_entries;
- *_sids = sids;
- sids = NULL;
- wbc_status = WBC_ERR_SUCCESS;
-
- done:
- if (response.extra_data.data) {
- free(response.extra_data.data);
- }
- if (sids) {
- talloc_free(sids);
- }
-
- return wbc_status;
-}
-
-/* Lists Users */
-wbcErr wbcListUsers(const char *domain_name,
- uint32_t *_num_users,
- const char ***_users)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct winbindd_request request;
- struct winbindd_response response;
- uint32_t num_users = 0;
- const char **users = NULL;
- const char *next;
-
- /* Initialise request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- if (domain_name) {
- strncpy(request.domain_name, domain_name,
- sizeof(request.domain_name)-1);
- }
-
- wbc_status = wbcRequestResponse(WINBINDD_LIST_USERS,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- /* Look through extra data */
-
- next = (const char *)response.extra_data.data;
- while (next) {
- const char **tmp;
- const char *current = next;
- char *k = strchr(next, ',');
- if (k) {
- k[0] = '\0';
- next = k+1;
- } else {
- next = NULL;
- }
-
- tmp = talloc_realloc(NULL, users,
- const char *,
- num_users+1);
- BAIL_ON_PTR_ERROR(tmp, wbc_status);
- users = tmp;
-
- users[num_users] = talloc_strdup(users, current);
- BAIL_ON_PTR_ERROR(users[num_users], wbc_status);
-
- num_users++;
- }
-
- *_num_users = num_users;
- *_users = users;
- users = NULL;
- wbc_status = WBC_ERR_SUCCESS;
-
- done:
- if (response.extra_data.data) {
- free(response.extra_data.data);
- }
- if (users) {
- talloc_free(users);
- }
- return wbc_status;
-}
-
-/* Lists Groups */
-wbcErr wbcListGroups(const char *domain_name,
- uint32_t *_num_groups,
- const char ***_groups)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct winbindd_request request;
- struct winbindd_response response;
- uint32_t num_groups = 0;
- const char **groups = NULL;
- const char *next;
-
- /* Initialise request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- if (domain_name) {
- strncpy(request.domain_name, domain_name,
- sizeof(request.domain_name)-1);
- }
-
- wbc_status = wbcRequestResponse(WINBINDD_LIST_GROUPS,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- /* Look through extra data */
-
- next = (const char *)response.extra_data.data;
- while (next) {
- const char **tmp;
- const char *current = next;
- char *k = strchr(next, ',');
- if (k) {
- k[0] = '\0';
- next = k+1;
- } else {
- next = NULL;
- }
-
- tmp = talloc_realloc(NULL, groups,
- const char *,
- num_groups+1);
- BAIL_ON_PTR_ERROR(tmp, wbc_status);
- groups = tmp;
-
- groups[num_groups] = talloc_strdup(groups, current);
- BAIL_ON_PTR_ERROR(groups[num_groups], wbc_status);
-
- num_groups++;
- }
-
- *_num_groups = num_groups;
- *_groups = groups;
- groups = NULL;
- wbc_status = WBC_ERR_SUCCESS;
-
- done:
- if (response.extra_data.data) {
- free(response.extra_data.data);
- }
- if (groups) {
- talloc_free(groups);
- }
- return wbc_status;
-}
-
-wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid,
- char **pdomain,
- char **pfullname,
- enum wbcSidType *pname_type)
-{
- wbcErr wbc_status;
- char *domain = NULL;
- char *name = NULL;
- enum wbcSidType name_type;
-
- wbc_status = wbcLookupSid(sid, &domain, &name, &name_type);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- if (name_type == WBC_SID_NAME_USER) {
- uid_t uid;
- struct passwd *pwd;
-
- wbc_status = wbcSidToUid(sid, &uid);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- wbc_status = wbcGetpwuid(uid, &pwd);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- wbcFreeMemory(name);
-
- name = talloc_strdup(NULL, pwd->pw_gecos);
- BAIL_ON_PTR_ERROR(name, wbc_status);
- }
-
- wbc_status = WBC_ERR_SUCCESS;
-
- done:
- if (WBC_ERROR_IS_OK(wbc_status)) {
- *pdomain = domain;
- *pfullname = name;
- *pname_type = name_type;
- } else {
- wbcFreeMemory(domain);
- wbcFreeMemory(name);
- }
-
- return wbc_status;
-}
diff --git a/source3/nsswitch/libwbclient/wbc_util.c b/source3/nsswitch/libwbclient/wbc_util.c
deleted file mode 100644
index 7cfb64b87e..0000000000
--- a/source3/nsswitch/libwbclient/wbc_util.c
+++ /dev/null
@@ -1,672 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind client API
-
- Copyright (C) Gerald (Jerry) Carter 2007-2008
-
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* Required Headers */
-
-#include "libwbclient.h"
-
-
-
-/** @brief Ping winbindd to see if the daemon is running
- *
- * @return #wbcErr
- **/
-
-wbcErr wbcPing(void)
-{
- struct winbindd_request request;
- struct winbindd_response response;
-
- /* Initialize request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- return wbcRequestResponse(WINBINDD_PING, &request, &response);
-}
-
-wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **_details)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcInterfaceDetails *info;
- struct wbcDomainInfo *domain = NULL;
- struct winbindd_request request;
- struct winbindd_response response;
-
- /* Initialize request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- info = talloc(NULL, struct wbcInterfaceDetails);
- BAIL_ON_PTR_ERROR(info, wbc_status);
-
- /* first the interface version */
- wbc_status = wbcRequestResponse(WINBINDD_INTERFACE_VERSION, NULL, &response);
- BAIL_ON_WBC_ERROR(wbc_status);
- info->interface_version = response.data.interface_version;
-
- /* then the samba version and the winbind separator */
- wbc_status = wbcRequestResponse(WINBINDD_INFO, NULL, &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- info->winbind_version = talloc_strdup(info,
- response.data.info.samba_version);
- BAIL_ON_PTR_ERROR(info->winbind_version, wbc_status);
- info->winbind_separator = response.data.info.winbind_separator;
-
- /* then the local netbios name */
- wbc_status = wbcRequestResponse(WINBINDD_NETBIOS_NAME, NULL, &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- info->netbios_name = talloc_strdup(info,
- response.data.netbios_name);
- BAIL_ON_PTR_ERROR(info->netbios_name, wbc_status);
-
- /* then the local workgroup name */
- wbc_status = wbcRequestResponse(WINBINDD_DOMAIN_NAME, NULL, &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- info->netbios_domain = talloc_strdup(info,
- response.data.domain_name);
- BAIL_ON_PTR_ERROR(info->netbios_domain, wbc_status);
-
- wbc_status = wbcDomainInfo(info->netbios_domain, &domain);
- if (wbc_status == WBC_ERR_DOMAIN_NOT_FOUND) {
- /* maybe it's a standalone server */
- domain = NULL;
- wbc_status = WBC_ERR_SUCCESS;
- } else {
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- if (domain) {
- info->dns_domain = talloc_strdup(info,
- domain->dns_name);
- wbcFreeMemory(domain);
- BAIL_ON_PTR_ERROR(info->dns_domain, wbc_status);
- } else {
- info->dns_domain = NULL;
- }
-
- *_details = info;
- info = NULL;
-
- wbc_status = WBC_ERR_SUCCESS;
-
-done:
- talloc_free(info);
- return wbc_status;
-}
-
-
-/* Lookup the current status of a trusted domain */
-wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcDomainInfo *info = NULL;
-
- if (!domain || !dinfo) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- /* Initialize request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- strncpy(request.domain_name, domain,
- sizeof(request.domain_name)-1);
-
- wbc_status = wbcRequestResponse(WINBINDD_DOMAIN_INFO,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- info = talloc(NULL, struct wbcDomainInfo);
- BAIL_ON_PTR_ERROR(info, wbc_status);
-
- info->short_name = talloc_strdup(info,
- response.data.domain_info.name);
- BAIL_ON_PTR_ERROR(info->short_name, wbc_status);
-
- info->dns_name = talloc_strdup(info,
- response.data.domain_info.alt_name);
- BAIL_ON_PTR_ERROR(info->dns_name, wbc_status);
-
- wbc_status = wbcStringToSid(response.data.domain_info.sid,
- &info->sid);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- if (response.data.domain_info.native_mode)
- info->domain_flags |= WBC_DOMINFO_DOMAIN_NATIVE;
- if (response.data.domain_info.active_directory)
- info->domain_flags |= WBC_DOMINFO_DOMAIN_AD;
- if (response.data.domain_info.primary)
- info->domain_flags |= WBC_DOMINFO_DOMAIN_PRIMARY;
-
- *dinfo = info;
-
- wbc_status = WBC_ERR_SUCCESS;
-
- done:
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- talloc_free(info);
- }
-
- return wbc_status;
-}
-
-
-/* Resolve a NetbiosName via WINS */
-wbcErr wbcResolveWinsByName(const char *name, char **ip)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *ipaddr;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Send request */
-
- strncpy(request.data.winsreq, name,
- sizeof(request.data.winsreq)-1);
-
- wbc_status = wbcRequestResponse(WINBINDD_WINS_BYNAME,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- /* Display response */
-
- ipaddr = talloc_strdup(NULL, response.data.winsresp);
- BAIL_ON_PTR_ERROR(ipaddr, wbc_status);
-
- *ip = ipaddr;
- wbc_status = WBC_ERR_SUCCESS;
-
- done:
- return wbc_status;
-}
-
-/* Resolve an IP address via WINS into a NetbiosName */
-wbcErr wbcResolveWinsByIP(const char *ip, char **name)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *name_str;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Send request */
-
- strncpy(request.data.winsreq, ip,
- sizeof(request.data.winsreq)-1);
-
- wbc_status = wbcRequestResponse(WINBINDD_WINS_BYIP,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- /* Display response */
-
- name_str = talloc_strdup(NULL, response.data.winsresp);
- BAIL_ON_PTR_ERROR(name_str, wbc_status);
-
- *name = name_str;
- wbc_status = WBC_ERR_SUCCESS;
-
- done:
- return wbc_status;
-}
-
-/**
- */
-
-static wbcErr process_domain_info_string(TALLOC_CTX *ctx,
- struct wbcDomainInfo *info,
- char *info_string)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *r = NULL;
- char *s = NULL;
-
- if (!info || !info_string) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- r = info_string;
-
- /* Short Name */
- if ((s = strchr(r, '\\')) == NULL) {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- *s = '\0';
- s++;
-
- info->short_name = talloc_strdup(ctx, r);
- BAIL_ON_PTR_ERROR(info->short_name, wbc_status);
-
-
- /* DNS Name */
- r = s;
- if ((s = strchr(r, '\\')) == NULL) {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- *s = '\0';
- s++;
-
- info->dns_name = talloc_strdup(ctx, r);
- BAIL_ON_PTR_ERROR(info->dns_name, wbc_status);
-
- /* SID */
- r = s;
- if ((s = strchr(r, '\\')) == NULL) {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- *s = '\0';
- s++;
-
- wbc_status = wbcStringToSid(r, &info->sid);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- /* Trust type */
- r = s;
- if ((s = strchr(r, '\\')) == NULL) {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- *s = '\0';
- s++;
-
- if (strcmp(r, "None") == 0) {
- info->trust_type = WBC_DOMINFO_TRUSTTYPE_NONE;
- } else if (strcmp(r, "External") == 0) {
- info->trust_type = WBC_DOMINFO_TRUSTTYPE_EXTERNAL;
- } else if (strcmp(r, "Forest") == 0) {
- info->trust_type = WBC_DOMINFO_TRUSTTYPE_FOREST;
- } else if (strcmp(r, "In Forest") == 0) {
- info->trust_type = WBC_DOMINFO_TRUSTTYPE_IN_FOREST;
- } else {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- /* Transitive */
- r = s;
- if ((s = strchr(r, '\\')) == NULL) {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- *s = '\0';
- s++;
-
- if (strcmp(r, "Yes") == 0) {
- info->trust_flags |= WBC_DOMINFO_TRUST_TRANSITIVE;
- }
-
- /* Incoming */
- r = s;
- if ((s = strchr(r, '\\')) == NULL) {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- *s = '\0';
- s++;
-
- if (strcmp(r, "Yes") == 0) {
- info->trust_flags |= WBC_DOMINFO_TRUST_INCOMING;
- }
-
- /* Outgoing */
- r = s;
- if ((s = strchr(r, '\\')) == NULL) {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- *s = '\0';
- s++;
-
- if (strcmp(r, "Yes") == 0) {
- info->trust_flags |= WBC_DOMINFO_TRUST_OUTGOING;
- }
-
- /* Online/Offline status */
-
- r = s;
- if (r == NULL) {
- wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
- if ( strcmp(r, "Offline") == 0) {
- info->domain_flags |= WBC_DOMINFO_DOMAIN_OFFLINE;
- }
-
- wbc_status = WBC_ERR_SUCCESS;
-
- done:
- return wbc_status;
-}
-
-/* Enumerate the domain trusts known by Winbind */
-wbcErr wbcListTrusts(struct wbcDomainInfo **domains, size_t *num_domains)
-{
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *p = NULL;
- char *q = NULL;
- char *extra_data = NULL;
- int count = 0;
- struct wbcDomainInfo *d_list = NULL;
- int i = 0;
-
- *domains = NULL;
- *num_domains = 0;
-
- ZERO_STRUCT(response);
-
- /* Send request */
-
- wbc_status = wbcRequestResponse(WINBINDD_LIST_TRUSTDOM,
- NULL,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- /* Decode the response */
-
- p = (char *)response.extra_data.data;
-
- if (strlen(p) == 0) {
- /* We should always at least get back our
- own SAM domain */
-
- wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- /* Count number of domains */
-
- count = 0;
- while (p) {
- count++;
-
- if ((q = strchr(p, '\n')) != NULL)
- q++;
- p = q;
- }
-
- d_list = talloc_array(NULL, struct wbcDomainInfo, count);
- BAIL_ON_PTR_ERROR(d_list, wbc_status);
-
- extra_data = strdup((char*)response.extra_data.data);
- BAIL_ON_PTR_ERROR(extra_data, wbc_status);
-
- p = extra_data;
-
- /* Outer loop processes the list of domain information */
-
- for (i=0; i<count && p; i++) {
- char *next = strchr(p, '\n');
-
- if (next) {
- *next = '\0';
- next++;
- }
-
- wbc_status = process_domain_info_string(d_list, &d_list[i], p);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- p = next;
- }
-
- *domains = d_list;
- *num_domains = i;
-
- done:
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- if (d_list)
- talloc_free(d_list);
- if (extra_data)
- free(extra_data);
- }
-
- return wbc_status;
-}
-
-/* Enumerate the domain trusts known by Winbind */
-wbcErr wbcLookupDomainController(const char *domain,
- uint32_t flags,
- struct wbcDomainControllerInfo **dc_info)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct winbindd_request request;
- struct winbindd_response response;
- struct wbcDomainControllerInfo *dc = NULL;
-
- /* validate input params */
-
- if (!domain || !dc_info) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- strncpy(request.domain_name, domain, sizeof(request.domain_name)-1);
-
- request.flags = flags;
-
- dc = talloc(NULL, struct wbcDomainControllerInfo);
- BAIL_ON_PTR_ERROR(dc, wbc_status);
-
- /* Send request */
-
- wbc_status = wbcRequestResponse(WINBINDD_DSGETDCNAME,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- dc->dc_name = talloc_strdup(dc, response.data.dc_name);
- BAIL_ON_PTR_ERROR(dc->dc_name, wbc_status);
-
- *dc_info = dc;
-
-done:
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- talloc_free(dc);
- }
-
- return wbc_status;
-}
-
-static wbcErr wbc_create_domain_controller_info_ex(TALLOC_CTX *mem_ctx,
- const struct winbindd_response *resp,
- struct wbcDomainControllerInfoEx **_i)
-{
- wbcErr wbc_status = WBC_ERR_SUCCESS;
- struct wbcDomainControllerInfoEx *i;
- struct wbcGuid guid;
-
- i = talloc(mem_ctx, struct wbcDomainControllerInfoEx);
- BAIL_ON_PTR_ERROR(i, wbc_status);
-
- i->dc_unc = talloc_strdup(i, resp->data.dsgetdcname.dc_unc);
- BAIL_ON_PTR_ERROR(i->dc_unc, wbc_status);
-
- i->dc_address = talloc_strdup(i, resp->data.dsgetdcname.dc_address);
- BAIL_ON_PTR_ERROR(i->dc_address, wbc_status);
-
- i->dc_address_type = resp->data.dsgetdcname.dc_address_type;
-
- wbc_status = wbcStringToGuid(resp->data.dsgetdcname.domain_guid, &guid);
- if (WBC_ERROR_IS_OK(wbc_status)) {
- i->domain_guid = talloc(i, struct wbcGuid);
- BAIL_ON_PTR_ERROR(i->domain_guid, wbc_status);
-
- *i->domain_guid = guid;
- } else {
- i->domain_guid = NULL;
- }
-
- i->domain_name = talloc_strdup(i, resp->data.dsgetdcname.domain_name);
- BAIL_ON_PTR_ERROR(i->domain_name, wbc_status);
-
- if (resp->data.dsgetdcname.forest_name[0] != '\0') {
- i->forest_name = talloc_strdup(i,
- resp->data.dsgetdcname.forest_name);
- BAIL_ON_PTR_ERROR(i->forest_name, wbc_status);
- } else {
- i->forest_name = NULL;
- }
-
- i->dc_flags = resp->data.dsgetdcname.dc_flags;
-
- if (resp->data.dsgetdcname.dc_site_name[0] != '\0') {
- i->dc_site_name = talloc_strdup(i,
- resp->data.dsgetdcname.dc_site_name);
- BAIL_ON_PTR_ERROR(i->dc_site_name, wbc_status);
- } else {
- i->dc_site_name = NULL;
- }
-
- if (resp->data.dsgetdcname.client_site_name[0] != '\0') {
- i->client_site_name = talloc_strdup(i,
- resp->data.dsgetdcname.client_site_name);
- BAIL_ON_PTR_ERROR(i->client_site_name, wbc_status);
- } else {
- i->client_site_name = NULL;
- }
-
- *_i = i;
- i = NULL;
-
-done:
- talloc_free(i);
- return wbc_status;
-}
-
-/* Get extended domain controller information */
-wbcErr wbcLookupDomainControllerEx(const char *domain,
- struct wbcGuid *guid,
- const char *site,
- uint32_t flags,
- struct wbcDomainControllerInfoEx **dc_info)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct winbindd_request request;
- struct winbindd_response response;
-
- /* validate input params */
-
- if (!domain || !dc_info) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- request.data.dsgetdcname.flags = flags;
-
- strncpy(request.data.dsgetdcname.domain_name, domain,
- sizeof(request.data.dsgetdcname.domain_name)-1);
-
- if (site) {
- strncpy(request.data.dsgetdcname.site_name, site,
- sizeof(request.data.dsgetdcname.site_name)-1);
- }
-
- if (guid) {
- char *str = NULL;
-
- wbc_status = wbcGuidToString(guid, &str);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.dsgetdcname.domain_guid, str,
- sizeof(request.data.dsgetdcname.domain_guid)-1);
-
- wbcFreeMemory(str);
- }
-
- /* Send request */
-
- wbc_status = wbcRequestResponse(WINBINDD_DSGETDCNAME,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- if (dc_info) {
- wbc_status = wbc_create_domain_controller_info_ex(NULL,
- &response,
- dc_info);
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- wbc_status = WBC_ERR_SUCCESS;
-done:
- return wbc_status;
-}
-
-/* Initialize a named blob and add to list of blobs */
-wbcErr wbcAddNamedBlob(size_t *num_blobs,
- struct wbcNamedBlob **blobs,
- const char *name,
- uint32_t flags,
- uint8_t *data,
- size_t length)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcNamedBlob blob;
-
- *blobs = talloc_realloc(NULL, *blobs, struct wbcNamedBlob,
- *(num_blobs)+1);
- BAIL_ON_PTR_ERROR(*blobs, wbc_status);
-
- blob.name = talloc_strdup(*blobs, name);
- BAIL_ON_PTR_ERROR(blob.name, wbc_status);
- blob.flags = flags;
- blob.blob.length = length;
- blob.blob.data = (uint8_t *)talloc_memdup(*blobs, data, length);
- BAIL_ON_PTR_ERROR(blob.blob.data, wbc_status);
-
- (*(blobs))[*num_blobs] = blob;
- *(num_blobs) += 1;
-
- wbc_status = WBC_ERR_SUCCESS;
-done:
- if (!WBC_ERROR_IS_OK(wbc_status) && blobs) {
- wbcFreeMemory(*blobs);
- }
- return wbc_status;
-}
diff --git a/source3/nsswitch/libwbclient/wbclient.c b/source3/nsswitch/libwbclient/wbclient.c
deleted file mode 100644
index 3a9afad15d..0000000000
--- a/source3/nsswitch/libwbclient/wbclient.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind client API
-
- Copyright (C) Gerald (Jerry) Carter 2007
-
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* Required Headers */
-
-#include "libwbclient.h"
-
-/* From wb_common.c */
-
-NSS_STATUS winbindd_request_response(int req_type,
- struct winbindd_request *request,
- struct winbindd_response *response);
-
-/** @brief Wrapper around Winbind's send/receive API call
- *
- * @param cmd Winbind command operation to perform
- * @param request Send structure
- * @param response Receive structure
- *
- * @return #wbcErr
- **/
-
-/**********************************************************************
- result == NSS_STATUS_UNAVAIL: winbind not around
- result == NSS_STATUS_NOTFOUND: winbind around, but domain missing
-
- Due to a bad API NSS_STATUS_NOTFOUND is returned both when winbind_off
- and when winbind return WINBINDD_ERROR. So the semantics of this
- routine depends on winbind_on. Grepping for winbind_off I just
- found 3 places where winbind is turned off, and this does not conflict
- (as far as I have seen) with the callers of is_trusted_domains.
-
- --Volker
-**********************************************************************/
-
-wbcErr wbcRequestResponse(int cmd,
- struct winbindd_request *request,
- struct winbindd_response *response)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- NSS_STATUS nss_status;
-
- /* for some calls the request and/or response can be NULL */
-
- nss_status = winbindd_request_response(cmd, request, response);
-
- switch (nss_status) {
- case NSS_STATUS_SUCCESS:
- wbc_status = WBC_ERR_SUCCESS;
- break;
- case NSS_STATUS_UNAVAIL:
- wbc_status = WBC_ERR_WINBIND_NOT_AVAILABLE;
- break;
- case NSS_STATUS_NOTFOUND:
- wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
- break;
- default:
- wbc_status = WBC_ERR_NSS_ERROR;
- break;
- }
-
- return wbc_status;
-}
-
-/** @brief Translate an error value into a string
- *
- * @param error
- *
- * @return a pointer to a static string
- **/
-const char *wbcErrorString(wbcErr error)
-{
- switch (error) {
- case WBC_ERR_SUCCESS:
- return "WBC_ERR_SUCCESS";
- case WBC_ERR_NOT_IMPLEMENTED:
- return "WBC_ERR_NOT_IMPLEMENTED";
- case WBC_ERR_UNKNOWN_FAILURE:
- return "WBC_ERR_UNKNOWN_FAILURE";
- case WBC_ERR_NO_MEMORY:
- return "WBC_ERR_NO_MEMORY";
- case WBC_ERR_INVALID_SID:
- return "WBC_ERR_INVALID_SID";
- case WBC_ERR_INVALID_PARAM:
- return "WBC_ERR_INVALID_PARAM";
- case WBC_ERR_WINBIND_NOT_AVAILABLE:
- return "WBC_ERR_WINBIND_NOT_AVAILABLE";
- case WBC_ERR_DOMAIN_NOT_FOUND:
- return "WBC_ERR_DOMAIN_NOT_FOUND";
- case WBC_ERR_INVALID_RESPONSE:
- return "WBC_ERR_INVALID_RESPONSE";
- case WBC_ERR_NSS_ERROR:
- return "WBC_ERR_NSS_ERROR";
- case WBC_ERR_UNKNOWN_USER:
- return "WBC_ERR_UNKNOWN_USER";
- case WBC_ERR_UNKNOWN_GROUP:
- return "WBC_ERR_UNKNOWN_GROUP";
- case WBC_ERR_AUTH_ERROR:
- return "WBC_ERR_AUTH_ERROR";
- case WBC_ERR_PWD_CHANGE_FAILED:
- return "WBC_ERR_PWD_CHANGE_FAILED";
- }
-
- return "unknown wbcErr value";
-}
-
-/* Free library allocated memory */
-void wbcFreeMemory(void *p)
-{
- if (p)
- talloc_free(p);
-
- return;
-}
-
-wbcErr wbcLibraryDetails(struct wbcLibraryDetails **_details)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcLibraryDetails *info;
-
- info = talloc(NULL, struct wbcLibraryDetails);
- BAIL_ON_PTR_ERROR(info, wbc_status);
-
- info->major_version = WBCLIENT_MAJOR_VERSION;
- info->minor_version = WBCLIENT_MINOR_VERSION;
- info->vendor_version = talloc_strdup(info,
- WBCLIENT_VENDOR_VERSION);
- BAIL_ON_PTR_ERROR(info->vendor_version, wbc_status);
-
- *_details = info;
- info = NULL;
-
- wbc_status = WBC_ERR_SUCCESS;
-
-done:
- talloc_free(info);
- return wbc_status;
-}
-
-
diff --git a/source3/nsswitch/libwbclient/wbclient.h b/source3/nsswitch/libwbclient/wbclient.h
deleted file mode 100644
index fcad3ff69b..0000000000
--- a/source3/nsswitch/libwbclient/wbclient.h
+++ /dev/null
@@ -1,1187 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind client API
-
- Copyright (C) Gerald (Jerry) Carter 2007
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _WBCLIENT_H
-#define _WBCLIENT_H
-
-#include <pwd.h>
-#include <grp.h>
-
-/* Define error types */
-
-/**
- * @brief Status codes returned from wbc functions
- **/
-
-enum _wbcErrType {
- WBC_ERR_SUCCESS = 0, /**< Successful completion **/
- WBC_ERR_NOT_IMPLEMENTED,/**< Function not implemented **/
- WBC_ERR_UNKNOWN_FAILURE,/**< General failure **/
- WBC_ERR_NO_MEMORY, /**< Memory allocation error **/
- WBC_ERR_INVALID_SID, /**< Invalid SID format **/
- WBC_ERR_INVALID_PARAM, /**< An Invalid parameter was supplied **/
- WBC_ERR_WINBIND_NOT_AVAILABLE, /**< Winbind daemon is not available **/
- WBC_ERR_DOMAIN_NOT_FOUND, /**< Domain is not trusted or cannot be found **/
- WBC_ERR_INVALID_RESPONSE, /**< Winbind returned an invalid response **/
- WBC_ERR_NSS_ERROR, /**< NSS_STATUS error **/
- WBC_ERR_AUTH_ERROR, /**< Authentication failed **/
- WBC_ERR_UNKNOWN_USER, /**< User account cannot be found */
- WBC_ERR_UNKNOWN_GROUP, /**< Group account cannot be found */
- WBC_ERR_PWD_CHANGE_FAILED /**< Password Change has failed */
-};
-
-typedef enum _wbcErrType wbcErr;
-
-#define WBC_ERROR_IS_OK(x) ((x) == WBC_ERR_SUCCESS)
-
-const char *wbcErrorString(wbcErr error);
-
-/**
- * @brief Some useful details about the wbclient library
- *
- * 0.1: Initial version
- * 0.2: Added wbcRemoveUidMapping()
- * Added wbcRemoveGidMapping()
- **/
-#define WBCLIENT_MAJOR_VERSION 0
-#define WBCLIENT_MINOR_VERSION 2
-#define WBCLIENT_VENDOR_VERSION "Samba libwbclient"
-struct wbcLibraryDetails {
- uint16_t major_version;
- uint16_t minor_version;
- const char *vendor_version;
-};
-
-/**
- * @brief Some useful details about the running winbindd
- *
- **/
-struct wbcInterfaceDetails {
- uint32_t interface_version;
- const char *winbind_version;
- char winbind_separator;
- const char *netbios_name;
- const char *netbios_domain;
- const char *dns_domain;
-};
-
-/*
- * Data types used by the Winbind Client API
- */
-
-#ifndef WBC_MAXSUBAUTHS
-#define WBC_MAXSUBAUTHS 15 /* max sub authorities in a SID */
-#endif
-
-/**
- * @brief Windows Security Identifier
- *
- **/
-
-struct wbcDomainSid {
- uint8_t sid_rev_num;
- uint8_t num_auths;
- uint8_t id_auth[6];
- uint32_t sub_auths[WBC_MAXSUBAUTHS];
-};
-
-/**
- * @brief Security Identifier type
- **/
-
-enum wbcSidType {
- WBC_SID_NAME_USE_NONE=0,
- WBC_SID_NAME_USER=1,
- WBC_SID_NAME_DOM_GRP=2,
- WBC_SID_NAME_DOMAIN=3,
- WBC_SID_NAME_ALIAS=4,
- WBC_SID_NAME_WKN_GRP=5,
- WBC_SID_NAME_DELETED=6,
- WBC_SID_NAME_INVALID=7,
- WBC_SID_NAME_UNKNOWN=8,
- WBC_SID_NAME_COMPUTER=9
-};
-
-/**
- * @brief Security Identifier with attributes
- **/
-
-struct wbcSidWithAttr {
- struct wbcDomainSid sid;
- uint32_t attributes;
-};
-
-/* wbcSidWithAttr->attributes */
-
-#define WBC_SID_ATTR_GROUP_MANDATORY 0x00000001
-#define WBC_SID_ATTR_GROUP_ENABLED_BY_DEFAULT 0x00000002
-#define WBC_SID_ATTR_GROUP_ENABLED 0x00000004
-#define WBC_SID_ATTR_GROUP_OWNER 0x00000008
-#define WBC_SID_ATTR_GROUP_USEFOR_DENY_ONLY 0x00000010
-#define WBC_SID_ATTR_GROUP_RESOURCE 0x20000000
-#define WBC_SID_ATTR_GROUP_LOGON_ID 0xC0000000
-
-/**
- * @brief Windows GUID
- *
- **/
-
-struct wbcGuid {
- uint32_t time_low;
- uint16_t time_mid;
- uint16_t time_hi_and_version;
- uint8_t clock_seq[2];
- uint8_t node[6];
-};
-
-/**
- * @brief Domain Information
- **/
-
-struct wbcDomainInfo {
- char *short_name;
- char *dns_name;
- struct wbcDomainSid sid;
- uint32_t domain_flags;
- uint32_t trust_flags;
- uint32_t trust_type;
-};
-
-/* wbcDomainInfo->domain_flags */
-
-#define WBC_DOMINFO_DOMAIN_UNKNOWN 0x00000000
-#define WBC_DOMINFO_DOMAIN_NATIVE 0x00000001
-#define WBC_DOMINFO_DOMAIN_AD 0x00000002
-#define WBC_DOMINFO_DOMAIN_PRIMARY 0x00000004
-#define WBC_DOMINFO_DOMAIN_OFFLINE 0x00000008
-
-/* wbcDomainInfo->trust_flags */
-
-#define WBC_DOMINFO_TRUST_TRANSITIVE 0x00000001
-#define WBC_DOMINFO_TRUST_INCOMING 0x00000002
-#define WBC_DOMINFO_TRUST_OUTGOING 0x00000004
-
-/* wbcDomainInfo->trust_type */
-
-#define WBC_DOMINFO_TRUSTTYPE_NONE 0x00000000
-#define WBC_DOMINFO_TRUSTTYPE_FOREST 0x00000001
-#define WBC_DOMINFO_TRUSTTYPE_IN_FOREST 0x00000002
-#define WBC_DOMINFO_TRUSTTYPE_EXTERNAL 0x00000003
-
-
-/**
- * @brief Auth User Parameters
- **/
-
-struct wbcAuthUserParams {
- const char *account_name;
- const char *domain_name;
- const char *workstation_name;
-
- uint32_t flags;
-
- uint32_t parameter_control;
-
- enum wbcAuthUserLevel {
- WBC_AUTH_USER_LEVEL_PLAIN = 1,
- WBC_AUTH_USER_LEVEL_HASH = 2,
- WBC_AUTH_USER_LEVEL_RESPONSE = 3
- } level;
- union {
- const char *plaintext;
- struct {
- uint8_t nt_hash[16];
- uint8_t lm_hash[16];
- } hash;
- struct {
- uint8_t challenge[8];
- uint32_t nt_length;
- uint8_t *nt_data;
- uint32_t lm_length;
- uint8_t *lm_data;
- } response;
- } password;
-};
-
-/**
- * @brief Generic Blob
- **/
-
-struct wbcBlob {
- uint8_t *data;
- size_t length;
-};
-
-/**
- * @brief Named Blob
- **/
-
-struct wbcNamedBlob {
- const char *name;
- uint32_t flags;
- struct wbcBlob blob;
-};
-
-/**
- * @brief Logon User Parameters
- **/
-
-struct wbcLogonUserParams {
- const char *username;
- const char *password;
- size_t num_blobs;
- struct wbcNamedBlob *blobs;
-};
-
-/**
- * @brief ChangePassword Parameters
- **/
-
-struct wbcChangePasswordParams {
- const char *account_name;
- const char *domain_name;
-
- uint32_t flags;
-
- enum wbcChangePasswordLevel {
- WBC_CHANGE_PASSWORD_LEVEL_PLAIN = 1,
- WBC_CHANGE_PASSWORD_LEVEL_RESPONSE = 2
- } level;
-
- union {
- const char *plaintext;
- struct {
- uint32_t old_nt_hash_enc_length;
- uint8_t *old_nt_hash_enc_data;
- uint32_t old_lm_hash_enc_length;
- uint8_t *old_lm_hash_enc_data;
- } response;
- } old_password;
- union {
- const char *plaintext;
- struct {
- uint32_t nt_length;
- uint8_t *nt_data;
- uint32_t lm_length;
- uint8_t *lm_data;
- } response;
- } new_password;
-};
-
-/* wbcAuthUserParams->parameter_control */
-
-#define WBC_MSV1_0_CLEARTEXT_PASSWORD_ALLOWED 0x00000002
-#define WBC_MSV1_0_UPDATE_LOGON_STATISTICS 0x00000004
-#define WBC_MSV1_0_RETURN_USER_PARAMETERS 0x00000008
-#define WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT 0x00000020
-#define WBC_MSV1_0_RETURN_PROFILE_PATH 0x00000200
-#define WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT 0x00000800
-
-/* wbcAuthUserParams->flags */
-
-#define WBC_AUTH_PARAM_FLAGS_INTERACTIVE_LOGON 0x00000001
-
-/**
- * @brief Auth User Information
- *
- * Some of the strings are maybe NULL
- **/
-
-struct wbcAuthUserInfo {
- uint32_t user_flags;
-
- char *account_name;
- char *user_principal;
- char *full_name;
- char *domain_name;
- char *dns_domain_name;
-
- uint32_t acct_flags;
- uint8_t user_session_key[16];
- uint8_t lm_session_key[8];
-
- uint16_t logon_count;
- uint16_t bad_password_count;
-
- uint64_t logon_time;
- uint64_t logoff_time;
- uint64_t kickoff_time;
- uint64_t pass_last_set_time;
- uint64_t pass_can_change_time;
- uint64_t pass_must_change_time;
-
- char *logon_server;
- char *logon_script;
- char *profile_path;
- char *home_directory;
- char *home_drive;
-
- /*
- * the 1st one is the account sid
- * the 2nd one is the primary_group sid
- * followed by the rest of the groups
- */
- uint32_t num_sids;
- struct wbcSidWithAttr *sids;
-};
-
-/**
- * @brief Logon User Information
- *
- * Some of the strings are maybe NULL
- **/
-
-struct wbcLogonUserInfo {
- struct wbcAuthUserInfo *info;
- size_t num_blobs;
- struct wbcNamedBlob *blobs;
-};
-
-/* wbcAuthUserInfo->user_flags */
-
-#define WBC_AUTH_USER_INFO_GUEST 0x00000001
-#define WBC_AUTH_USER_INFO_NOENCRYPTION 0x00000002
-#define WBC_AUTH_USER_INFO_CACHED_ACCOUNT 0x00000004
-#define WBC_AUTH_USER_INFO_USED_LM_PASSWORD 0x00000008
-#define WBC_AUTH_USER_INFO_EXTRA_SIDS 0x00000020
-#define WBC_AUTH_USER_INFO_SUBAUTH_SESSION_KEY 0x00000040
-#define WBC_AUTH_USER_INFO_SERVER_TRUST_ACCOUNT 0x00000080
-#define WBC_AUTH_USER_INFO_NTLMV2_ENABLED 0x00000100
-#define WBC_AUTH_USER_INFO_RESOURCE_GROUPS 0x00000200
-#define WBC_AUTH_USER_INFO_PROFILE_PATH_RETURNED 0x00000400
-#define WBC_AUTH_USER_INFO_GRACE_LOGON 0x01000000
-
-/* wbcAuthUserInfo->acct_flags */
-
-#define WBC_ACB_DISABLED 0x00000001 /* 1 User account disabled */
-#define WBC_ACB_HOMDIRREQ 0x00000002 /* 1 Home directory required */
-#define WBC_ACB_PWNOTREQ 0x00000004 /* 1 User password not required */
-#define WBC_ACB_TEMPDUP 0x00000008 /* 1 Temporary duplicate account */
-#define WBC_ACB_NORMAL 0x00000010 /* 1 Normal user account */
-#define WBC_ACB_MNS 0x00000020 /* 1 MNS logon user account */
-#define WBC_ACB_DOMTRUST 0x00000040 /* 1 Interdomain trust account */
-#define WBC_ACB_WSTRUST 0x00000080 /* 1 Workstation trust account */
-#define WBC_ACB_SVRTRUST 0x00000100 /* 1 Server trust account */
-#define WBC_ACB_PWNOEXP 0x00000200 /* 1 User password does not expire */
-#define WBC_ACB_AUTOLOCK 0x00000400 /* 1 Account auto locked */
-#define WBC_ACB_ENC_TXT_PWD_ALLOWED 0x00000800 /* 1 Encryped text password is allowed */
-#define WBC_ACB_SMARTCARD_REQUIRED 0x00001000 /* 1 Smart Card required */
-#define WBC_ACB_TRUSTED_FOR_DELEGATION 0x00002000 /* 1 Trusted for Delegation */
-#define WBC_ACB_NOT_DELEGATED 0x00004000 /* 1 Not delegated */
-#define WBC_ACB_USE_DES_KEY_ONLY 0x00008000 /* 1 Use DES key only */
-#define WBC_ACB_DONT_REQUIRE_PREAUTH 0x00010000 /* 1 Preauth not required */
-#define WBC_ACB_PW_EXPIRED 0x00020000 /* 1 Password Expired */
-#define WBC_ACB_NO_AUTH_DATA_REQD 0x00080000 /* 1 = No authorization data required */
-
-struct wbcAuthErrorInfo {
- uint32_t nt_status;
- char *nt_string;
- int32_t pam_error;
- char *display_string;
-};
-
-/**
- * @brief User Password Policy Information
- **/
-
-/* wbcUserPasswordPolicyInfo->password_properties */
-
-#define WBC_DOMAIN_PASSWORD_COMPLEX 0x00000001
-#define WBC_DOMAIN_PASSWORD_NO_ANON_CHANGE 0x00000002
-#define WBC_DOMAIN_PASSWORD_NO_CLEAR_CHANGE 0x00000004
-#define WBC_DOMAIN_PASSWORD_LOCKOUT_ADMINS 0x00000008
-#define WBC_DOMAIN_PASSWORD_STORE_CLEARTEXT 0x00000010
-#define WBC_DOMAIN_REFUSE_PASSWORD_CHANGE 0x00000020
-
-struct wbcUserPasswordPolicyInfo {
- uint32_t min_length_password;
- uint32_t password_history;
- uint32_t password_properties;
- uint64_t expire;
- uint64_t min_passwordage;
-};
-
-/**
- * @brief Change Password Reject Reason
- **/
-
-enum wbcPasswordChangeRejectReason {
- WBC_PWD_CHANGE_REJECT_OTHER=0,
- WBC_PWD_CHANGE_REJECT_TOO_SHORT=1,
- WBC_PWD_CHANGE_REJECT_IN_HISTORY=2,
- WBC_PWD_CHANGE_REJECT_COMPLEXITY=5
-};
-
-/**
- * @brief Logoff User Parameters
- **/
-
-struct wbcLogoffUserParams {
- const char *username;
- size_t num_blobs;
- struct wbcNamedBlob *blobs;
-};
-
-/** @brief Credential cache log-on parameters
- *
- */
-
-struct wbcCredentialCacheParams {
- const char *account_name;
- const char *domain_name;
- enum wbcCredentialCacheLevel {
- WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP = 1
- } level;
- size_t num_blobs;
- struct wbcNamedBlob *blobs;
-};
-
-
-/** @brief Info returned by credential cache auth
- *
- */
-
-struct wbcCredentialCacheInfo {
- size_t num_blobs;
- struct wbcNamedBlob *blobs;
-};
-
-/*
- * DomainControllerInfo struct
- */
-struct wbcDomainControllerInfo {
- char *dc_name;
-};
-
-/*
- * DomainControllerInfoEx struct
- */
-struct wbcDomainControllerInfoEx {
- const char *dc_unc;
- const char *dc_address;
- uint16_t dc_address_type;
- struct wbcGuid *domain_guid;
- const char *domain_name;
- const char *forest_name;
- uint32_t dc_flags;
- const char *dc_site_name;
- const char *client_site_name;
-};
-
-/**********************************************************
- * Memory Management
- **********************************************************/
-
-/**
- * @brief Free library allocated memory
- *
- * @param *p Pointer to free
- *
- * @return void
- **/
-void wbcFreeMemory(void*);
-
-
-/*
- * Utility functions for dealing with SIDs
- */
-
-/**
- * @brief Convert a binary SID to a character string
- *
- * @param sid Binary Security Identifier
- * @param **sid_string Resulting character string
- *
- * @return #wbcErr
- **/
-wbcErr wbcSidToString(const struct wbcDomainSid *sid,
- char **sid_string);
-
-/**
- * @brief Convert a character string to a binary SID
- *
- * @param *str Character string in the form of S-...
- * @param sid Resulting binary SID
- *
- * @return #wbcErr
- **/
-wbcErr wbcStringToSid(const char *sid_string,
- struct wbcDomainSid *sid);
-
-/*
- * Utility functions for dealing with GUIDs
- */
-
-/**
- * @brief Convert a binary GUID to a character string
- *
- * @param guid Binary Guid
- * @param **guid_string Resulting character string
- *
- * @return #wbcErr
- **/
-wbcErr wbcGuidToString(const struct wbcGuid *guid,
- char **guid_string);
-
-/**
- * @brief Convert a character string to a binary GUID
- *
- * @param *str Character string
- * @param guid Resulting binary GUID
- *
- * @return #wbcErr
- **/
-wbcErr wbcStringToGuid(const char *guid_string,
- struct wbcGuid *guid);
-
-/**
- * @brief Ping winbindd to see if the daemon is running
- *
- * @return #wbcErr
- **/
-wbcErr wbcPing(void);
-
-wbcErr wbcLibraryDetails(struct wbcLibraryDetails **details);
-
-wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **details);
-
-/**********************************************************
- * Name/SID conversion
- **********************************************************/
-
-/**
- * @brief Convert a domain and name to SID
- *
- * @param domain Domain name (possibly "")
- * @param name User or group name
- * @param *sid Pointer to the resolved domain SID
- * @param *name_type Pointer to the SID type
- *
- * @return #wbcErr
- **/
-wbcErr wbcLookupName(const char *dom_name,
- const char *name,
- struct wbcDomainSid *sid,
- enum wbcSidType *name_type);
-
-/**
- * @brief Convert a SID to a domain and name
- *
- * @param *sid Pointer to the domain SID to be resolved
- * @param pdomain Resolved Domain name (possibly "")
- * @param pname Resolved User or group name
- * @param *pname_type Pointer to the resolved SID type
- *
- * @return #wbcErr
- **/
-wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
- char **domain,
- char **name,
- enum wbcSidType *name_type);
-
-/**
- * @brief Translate a collection of RIDs within a domain to names
- */
-wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
- int num_rids,
- uint32_t *rids,
- const char **domain_name,
- const char ***names,
- enum wbcSidType **types);
-
-/*
- * @brief Get the groups a user belongs to
- **/
-wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid,
- bool domain_groups_only,
- uint32_t *num_sids,
- struct wbcDomainSid **sids);
-
-/**
- * @brief Lists Users
- **/
-wbcErr wbcListUsers(const char *domain_name,
- uint32_t *num_users,
- const char ***users);
-
-/**
- * @brief Lists Groups
- **/
-wbcErr wbcListGroups(const char *domain_name,
- uint32_t *num_groups,
- const char ***groups);
-
-wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid,
- char **pdomain,
- char **pfullname,
- enum wbcSidType *pname_type);
-
-/**********************************************************
- * SID/uid/gid Mappings
- **********************************************************/
-
-/**
- * @brief Convert a Windows SID to a Unix uid, allocating an uid if needed
- *
- * @param *sid Pointer to the domain SID to be resolved
- * @param *puid Pointer to the resolved uid_t value
- *
- * @return #wbcErr
- *
- **/
-wbcErr wbcSidToUid(const struct wbcDomainSid *sid,
- uid_t *puid);
-
-/**
- * @brief Convert a Windows SID to a Unix uid if there already is a mapping
- *
- * @param *sid Pointer to the domain SID to be resolved
- * @param *puid Pointer to the resolved uid_t value
- *
- * @return #wbcErr
- *
- **/
-wbcErr wbcQuerySidToUid(const struct wbcDomainSid *sid,
- uid_t *puid);
-
-/**
- * @brief Convert a Unix uid to a Windows SID, allocating a SID if needed
- *
- * @param uid Unix uid to be resolved
- * @param *sid Pointer to the resolved domain SID
- *
- * @return #wbcErr
- *
- **/
-wbcErr wbcUidToSid(uid_t uid,
- struct wbcDomainSid *sid);
-
-/**
- * @brief Convert a Unix uid to a Windows SID if there already is a mapping
- *
- * @param uid Unix uid to be resolved
- * @param *sid Pointer to the resolved domain SID
- *
- * @return #wbcErr
- *
- **/
-wbcErr wbcQueryUidToSid(uid_t uid,
- struct wbcDomainSid *sid);
-
-/**
- * @brief Convert a Windows SID to a Unix gid, allocating a gid if needed
- *
- * @param *sid Pointer to the domain SID to be resolved
- * @param *pgid Pointer to the resolved gid_t value
- *
- * @return #wbcErr
- *
- **/
-wbcErr wbcSidToGid(const struct wbcDomainSid *sid,
- gid_t *pgid);
-
-/**
- * @brief Convert a Windows SID to a Unix gid if there already is a mapping
- *
- * @param *sid Pointer to the domain SID to be resolved
- * @param *pgid Pointer to the resolved gid_t value
- *
- * @return #wbcErr
- *
- **/
-wbcErr wbcQuerySidToGid(const struct wbcDomainSid *sid,
- gid_t *pgid);
-
-/**
- * @brief Convert a Unix gid to a Windows SID, allocating a SID if needed
- *
- * @param gid Unix gid to be resolved
- * @param *sid Pointer to the resolved domain SID
- *
- * @return #wbcErr
- *
- **/
-wbcErr wbcGidToSid(gid_t gid,
- struct wbcDomainSid *sid);
-
-/**
- * @brief Convert a Unix gid to a Windows SID if there already is a mapping
- *
- * @param gid Unix gid to be resolved
- * @param *sid Pointer to the resolved domain SID
- *
- * @return #wbcErr
- *
- **/
-wbcErr wbcQueryGidToSid(gid_t gid,
- struct wbcDomainSid *sid);
-
-/**
- * @brief Obtain a new uid from Winbind
- *
- * @param *puid *pointer to the allocated uid
- *
- * @return #wbcErr
- **/
-wbcErr wbcAllocateUid(uid_t *puid);
-
-/**
- * @brief Obtain a new gid from Winbind
- *
- * @param *pgid Pointer to the allocated gid
- *
- * @return #wbcErr
- **/
-wbcErr wbcAllocateGid(gid_t *pgid);
-
-/**
- * @brief Set an user id mapping
- *
- * @param uid Uid of the desired mapping.
- * @param *sid Pointer to the sid of the diresired mapping.
- *
- * @return #wbcErr
- **/
-wbcErr wbcSetUidMapping(uid_t uid, const struct wbcDomainSid *sid);
-
-/**
- * @brief Set a group id mapping
- *
- * @param gid Gid of the desired mapping.
- * @param *sid Pointer to the sid of the diresired mapping.
- *
- * @return #wbcErr
- **/
-wbcErr wbcSetGidMapping(gid_t gid, const struct wbcDomainSid *sid);
-
-/**
- * @brief Remove a user id mapping
- *
- * @param uid Uid of the mapping to remove.
- * @param *sid Pointer to the sid of the mapping to remove.
- *
- * @return #wbcErr
- **/
-wbcErr wbcRemoveUidMapping(uid_t uid, const struct wbcDomainSid *sid);
-
-/**
- * @brief Remove a group id mapping
- *
- * @param gid Gid of the mapping to remove.
- * @param *sid Pointer to the sid of the mapping to remove.
- *
- * @return #wbcErr
- **/
-wbcErr wbcRemoveGidMapping(gid_t gid, const struct wbcDomainSid *sid);
-
-/**
- * @brief Set the highwater mark for allocated uids.
- *
- * @param uid_hwm The new uid highwater mark value
- *
- * @return #wbcErr
- **/
-wbcErr wbcSetUidHwm(uid_t uid_hwm);
-
-/**
- * @brief Set the highwater mark for allocated gids.
- *
- * @param gid_hwm The new gid highwater mark value
- *
- * @return #wbcErr
- **/
-wbcErr wbcSetGidHwm(gid_t gid_hwm);
-
-/**********************************************************
- * NSS Lookup User/Group details
- **********************************************************/
-
-/**
- * @brief Fill in a struct passwd* for a domain user based
- * on username
- *
- * @param *name Username to lookup
- * @param **pwd Pointer to resulting struct passwd* from the query.
- *
- * @return #wbcErr
- **/
-wbcErr wbcGetpwnam(const char *name, struct passwd **pwd);
-
-/**
- * @brief Fill in a struct passwd* for a domain user based
- * on uid
- *
- * @param uid Uid to lookup
- * @param **pwd Pointer to resulting struct passwd* from the query.
- *
- * @return #wbcErr
- **/
-wbcErr wbcGetpwuid(uid_t uid, struct passwd **pwd);
-
-/**
- * @brief Fill in a struct passwd* for a domain user based
- * on username
- *
- * @param *name Username to lookup
- * @param **grp Pointer to resulting struct group* from the query.
- *
- * @return #wbcErr
- **/
-wbcErr wbcGetgrnam(const char *name, struct group **grp);
-
-/**
- * @brief Fill in a struct passwd* for a domain user based
- * on uid
- *
- * @param gid Uid to lookup
- * @param **grp Pointer to resulting struct group* from the query.
- *
- * @return #wbcErr
- **/
-wbcErr wbcGetgrgid(gid_t gid, struct group **grp);
-
-/**
- * @brief Reset the passwd iterator
- *
- * @return #wbcErr
- **/
-wbcErr wbcSetpwent(void);
-
-/**
- * @brief Close the passwd iterator
- *
- * @return #wbcErr
- **/
-wbcErr wbcEndpwent(void);
-
-/**
- * @brief Return the next struct passwd* entry from the pwent iterator
- *
- * @param **pwd Pointer to resulting struct passwd* from the query.
- *
- * @return #wbcErr
- **/
-wbcErr wbcGetpwent(struct passwd **pwd);
-
-/**
- * @brief Reset the group iterator
- *
- * @return #wbcErr
- **/
-wbcErr wbcSetgrent(void);
-
-/**
- * @brief Close the group iterator
- *
- * @return #wbcErr
- **/
-wbcErr wbcEndgrent(void);
-
-/**
- * @brief Return the next struct group* entry from the pwent iterator
- *
- * @param **grp Pointer to resulting struct group* from the query.
- *
- * @return #wbcErr
- **/
-wbcErr wbcGetgrent(struct group **grp);
-
-/**
- * @brief Return the next struct group* entry from the pwent iterator
- *
- * This is similar to #wbcGetgrent, just that the member list is empty
- *
- * @param **grp Pointer to resulting struct group* from the query.
- *
- * @return #wbcErr
- **/
-wbcErr wbcGetgrlist(struct group **grp);
-
-/**
- * @brief Return the unix group array belonging to the given user
- *
- * @param *account The given user name
- * @param *num_groups Number of elements returned in the groups array
- * @param **_groups Pointer to resulting gid_t array.
- *
- * @return #wbcErr
- **/
-wbcErr wbcGetGroups(const char *account,
- uint32_t *num_groups,
- gid_t **_groups);
-
-
-/**********************************************************
- * Lookup Domain information
- **********************************************************/
-
-/**
- * @brief Lookup the current status of a trusted domain
- *
- * @param domain Domain to query
- * @param *dinfo Pointer to returned domain_info struct
- *
- * @return #wbcErr
- **/
-wbcErr wbcDomainInfo(const char *domain,
- struct wbcDomainInfo **info);
-
-/**
- * @brief Enumerate the domain trusts known by Winbind
- *
- * @param **domains Pointer to the allocated domain list array
- * @param *num_domains Pointer to number of domains returned
- *
- * @return #wbcErr
- **/
-wbcErr wbcListTrusts(struct wbcDomainInfo **domains,
- size_t *num_domains);
-
-/* Flags for wbcLookupDomainController */
-
-#define WBC_LOOKUP_DC_FORCE_REDISCOVERY 0x00000001
-#define WBC_LOOKUP_DC_DS_REQUIRED 0x00000010
-#define WBC_LOOKUP_DC_DS_PREFERRED 0x00000020
-#define WBC_LOOKUP_DC_GC_SERVER_REQUIRED 0x00000040
-#define WBC_LOOKUP_DC_PDC_REQUIRED 0x00000080
-#define WBC_LOOKUP_DC_BACKGROUND_ONLY 0x00000100
-#define WBC_LOOKUP_DC_IP_REQUIRED 0x00000200
-#define WBC_LOOKUP_DC_KDC_REQUIRED 0x00000400
-#define WBC_LOOKUP_DC_TIMESERV_REQUIRED 0x00000800
-#define WBC_LOOKUP_DC_WRITABLE_REQUIRED 0x00001000
-#define WBC_LOOKUP_DC_GOOD_TIMESERV_PREFERRED 0x00002000
-#define WBC_LOOKUP_DC_AVOID_SELF 0x00004000
-#define WBC_LOOKUP_DC_ONLY_LDAP_NEEDED 0x00008000
-#define WBC_LOOKUP_DC_IS_FLAT_NAME 0x00010000
-#define WBC_LOOKUP_DC_IS_DNS_NAME 0x00020000
-#define WBC_LOOKUP_DC_TRY_NEXTCLOSEST_SITE 0x00040000
-#define WBC_LOOKUP_DC_DS_6_REQUIRED 0x00080000
-#define WBC_LOOKUP_DC_RETURN_DNS_NAME 0x40000000
-#define WBC_LOOKUP_DC_RETURN_FLAT_NAME 0x80000000
-
-/**
- * @brief Enumerate the domain trusts known by Winbind
- *
- * @param domain Name of the domain to query for a DC
- * @param flags Bit flags used to control the domain location query
- * @param *dc_info Pointer to the returned domain controller information
- *
- * @return #wbcErr
- **/
-wbcErr wbcLookupDomainController(const char *domain,
- uint32_t flags,
- struct wbcDomainControllerInfo **dc_info);
-
-/**
- * @brief Get extended domain controller information
- *
- * @param domain Name of the domain to query for a DC
- * @param guid Guid of the domain to query for a DC
- * @param site Site of the domain to query for a DC
- * @param flags Bit flags used to control the domain location query
- * @param *dc_info Pointer to the returned extended domain controller information
- *
- * @return #wbcErr
- **/
-wbcErr wbcLookupDomainControllerEx(const char *domain,
- struct wbcGuid *guid,
- const char *site,
- uint32_t flags,
- struct wbcDomainControllerInfoEx **dc_info);
-
-/**********************************************************
- * Athenticate functions
- **********************************************************/
-
-/**
- * @brief Authenticate a username/password pair
- *
- * @param username Name of user to authenticate
- * @param password Clear text password os user
- *
- * @return #wbcErr
- **/
-wbcErr wbcAuthenticateUser(const char *username,
- const char *password);
-
-/**
- * @brief Authenticate with more detailed information
- *
- * @param params Input parameters, WBC_AUTH_USER_LEVEL_HASH
- * is not supported yet
- * @param info Output details on WBC_ERR_SUCCESS
- * @param error Output details on WBC_ERR_AUTH_ERROR
- *
- * @return #wbcErr
- **/
-wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params,
- struct wbcAuthUserInfo **info,
- struct wbcAuthErrorInfo **error);
-
-/**
- * @brief Logon a User
- *
- * @param[in] params Pointer to a wbcLogonUserParams structure
- * @param[out] info Pointer to a pointer to a wbcLogonUserInfo structure
- * @param[out] error Pointer to a pointer to a wbcAuthErrorInfo structure
- * @param[out] policy Pointer to a pointer to a wbcUserPasswordPolicyInfo structure
- *
- * @return #wbcErr
- **/
-wbcErr wbcLogonUser(const struct wbcLogonUserParams *params,
- struct wbcLogonUserInfo **info,
- struct wbcAuthErrorInfo **error,
- struct wbcUserPasswordPolicyInfo **policy);
-
-/**
- * @brief Trigger a logoff notification to Winbind for a specific user
- *
- * @param username Name of user to remove from Winbind's list of
- * logged on users.
- * @param uid Uid assigned to the username
- * @param ccfilename Absolute path to the Krb5 credentials cache to
- * be removed
- *
- * @return #wbcErr
- **/
-wbcErr wbcLogoffUser(const char *username,
- uid_t uid,
- const char *ccfilename);
-
-/**
- * @brief Trigger an extended logoff notification to Winbind for a specific user
- *
- * @param params A wbcLogoffUserParams structure
- * @param error User output details on error
- *
- * @return #wbcErr
- **/
-wbcErr wbcLogoffUserEx(const struct wbcLogoffUserParams *params,
- struct wbcAuthErrorInfo **error);
-
-/**
- * @brief Change a password for a user
- *
- * @param username Name of user to authenticate
- * @param old_password Old clear text password of user
- * @param new_password New clear text password of user
- *
- * @return #wbcErr
- **/
-wbcErr wbcChangeUserPassword(const char *username,
- const char *old_password,
- const char *new_password);
-
-/**
- * @brief Change a password for a user with more detailed information upon
- * failure
- *
- * @param params Input parameters
- * @param error User output details on WBC_ERR_PWD_CHANGE_FAILED
- * @param reject_reason New password reject reason on WBC_ERR_PWD_CHANGE_FAILED
- * @param policy Password policy output details on WBC_ERR_PWD_CHANGE_FAILED
- *
- * @return #wbcErr
- **/
-wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params,
- struct wbcAuthErrorInfo **error,
- enum wbcPasswordChangeRejectReason *reject_reason,
- struct wbcUserPasswordPolicyInfo **policy);
-
-/**
- * @brief Authenticate a user with cached credentials
- *
- * @param *params Pointer to a wbcCredentialCacheParams structure
- * @param **info Pointer to a pointer to a wbcCredentialCacheInfo structure
- * @param **error Pointer to a pointer to a wbcAuthErrorInfo structure
- *
- * @return #wbcErr
- **/
-wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params,
- struct wbcCredentialCacheInfo **info,
- struct wbcAuthErrorInfo **error);
-
-/**********************************************************
- * Resolve functions
- **********************************************************/
-
-/**
- * @brief Resolve a NetbiosName via WINS
- *
- * @param name Name to resolve
- * @param *ip Pointer to the ip address string
- *
- * @return #wbcErr
- **/
-wbcErr wbcResolveWinsByName(const char *name, char **ip);
-
-/**
- * @brief Resolve an IP address via WINS into a NetbiosName
- *
- * @param ip The ip address string
- * @param *name Pointer to the name
- *
- * @return #wbcErr
- *
- **/
-wbcErr wbcResolveWinsByIP(const char *ip, char **name);
-
-/**********************************************************
- * Trusted domain functions
- **********************************************************/
-
-/**
- * @brief Trigger a verification of the trust credentials of a specific domain
- *
- * @param *domain The name of the domain, only NULL for the default domain is
- * supported yet. Other values than NULL will result in
- * WBC_ERR_NOT_IMPLEMENTED.
- * @param error Output details on WBC_ERR_AUTH_ERROR
- *
- * @return #wbcErr
- **/
-wbcErr wbcCheckTrustCredentials(const char *domain,
- struct wbcAuthErrorInfo **error);
-
-/**********************************************************
- * Helper functions
- **********************************************************/
-
-/**
- * @brief Initialize a named blob and add to list of blobs
- *
- * @param[in,out] num_blobs Pointer to the number of blobs
- * @param[in,out] blobs Pointer to an array of blobs
- * @param[in] name Name of the new named blob
- * @param[in] flags Flags of the new named blob
- * @param[in] data Blob data of new blob
- * @param[in] length Blob data length of new blob
- *
- * @return #wbcErr
- **/
-wbcErr wbcAddNamedBlob(size_t *num_blobs,
- struct wbcNamedBlob **blobs,
- const char *name,
- uint32_t flags,
- uint8_t *data,
- size_t length);
-
-#endif /* _WBCLIENT_H */
diff --git a/source3/nsswitch/libwbclient/wbclient_internal.h b/source3/nsswitch/libwbclient/wbclient_internal.h
deleted file mode 100644
index fc03c5409b..0000000000
--- a/source3/nsswitch/libwbclient/wbclient_internal.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind client API
-
- Copyright (C) Gerald (Jerry) Carter 2007
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _WBCLIENT_INTERNAL_H
-#define _WBCLIENT_INTERNAL_H
-
-/* Private functions */
-
-wbcErr wbcRequestResponse(int cmd,
- struct winbindd_request *request,
- struct winbindd_response *response);
-
-
-#endif /* _WBCLIENT_INTERNAL_H */
diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c
deleted file mode 100644
index d049bdb1e7..0000000000
--- a/source3/nsswitch/pam_winbind.c
+++ /dev/null
@@ -1,3204 +0,0 @@
-/* pam_winbind module
-
- Copyright Andrew Tridgell <tridge@samba.org> 2000
- Copyright Tim Potter <tpot@samba.org> 2000
- Copyright Andrew Bartlett <abartlet@samba.org> 2002
- Copyright Guenther Deschner <gd@samba.org> 2005-2008
-
- largely based on pam_userdb by Cristian Gafton <gafton@redhat.com> also
- contains large slabs of code from pam_unix by Elliot Lee
- <sopwith@redhat.com> (see copyright below for full details)
-*/
-
-#include "pam_winbind.h"
-
-static int wbc_error_to_pam_error(wbcErr status)
-{
- switch (status) {
- case WBC_ERR_SUCCESS:
- return PAM_SUCCESS;
- case WBC_ERR_NOT_IMPLEMENTED:
- return PAM_SERVICE_ERR;
- case WBC_ERR_UNKNOWN_FAILURE:
- break;
- case WBC_ERR_NO_MEMORY:
- return PAM_BUF_ERR;
- case WBC_ERR_INVALID_SID:
- case WBC_ERR_INVALID_PARAM:
- break;
- case WBC_ERR_WINBIND_NOT_AVAILABLE:
- return PAM_AUTHINFO_UNAVAIL;
- case WBC_ERR_DOMAIN_NOT_FOUND:
- return PAM_AUTHINFO_UNAVAIL;
- case WBC_ERR_INVALID_RESPONSE:
- return PAM_BUF_ERR;
- case WBC_ERR_NSS_ERROR:
- return PAM_USER_UNKNOWN;
- case WBC_ERR_AUTH_ERROR:
- return PAM_AUTH_ERR;
- case WBC_ERR_UNKNOWN_USER:
- return PAM_USER_UNKNOWN;
- case WBC_ERR_UNKNOWN_GROUP:
- return PAM_USER_UNKNOWN;
- case WBC_ERR_PWD_CHANGE_FAILED:
- break;
- }
-
- /* be paranoid */
- return PAM_AUTH_ERR;
-}
-
-static const char *_pam_error_code_str(int err)
-{
- switch (err) {
- case PAM_SUCCESS:
- return "PAM_SUCCESS";
- case PAM_OPEN_ERR:
- return "PAM_OPEN_ERR";
- case PAM_SYMBOL_ERR:
- return "PAM_SYMBOL_ERR";
- case PAM_SERVICE_ERR:
- return "PAM_SERVICE_ERR";
- case PAM_SYSTEM_ERR:
- return "PAM_SYSTEM_ERR";
- case PAM_BUF_ERR:
- return "PAM_BUF_ERR";
- case PAM_PERM_DENIED:
- return "PAM_PERM_DENIED";
- case PAM_AUTH_ERR:
- return "PAM_AUTH_ERR";
- case PAM_CRED_INSUFFICIENT:
- return "PAM_CRED_INSUFFICIENT";
- case PAM_AUTHINFO_UNAVAIL:
- return "PAM_AUTHINFO_UNAVAIL";
- case PAM_USER_UNKNOWN:
- return "PAM_USER_UNKNOWN";
- case PAM_MAXTRIES:
- return "PAM_MAXTRIES";
- case PAM_NEW_AUTHTOK_REQD:
- return "PAM_NEW_AUTHTOK_REQD";
- case PAM_ACCT_EXPIRED:
- return "PAM_ACCT_EXPIRED";
- case PAM_SESSION_ERR:
- return "PAM_SESSION_ERR";
- case PAM_CRED_UNAVAIL:
- return "PAM_CRED_UNAVAIL";
- case PAM_CRED_EXPIRED:
- return "PAM_CRED_EXPIRED";
- case PAM_CRED_ERR:
- return "PAM_CRED_ERR";
- case PAM_NO_MODULE_DATA:
- return "PAM_NO_MODULE_DATA";
- case PAM_CONV_ERR:
- return "PAM_CONV_ERR";
- case PAM_AUTHTOK_ERR:
- return "PAM_AUTHTOK_ERR";
- case PAM_AUTHTOK_RECOVER_ERR:
- return "PAM_AUTHTOK_RECOVER_ERR";
- case PAM_AUTHTOK_LOCK_BUSY:
- return "PAM_AUTHTOK_LOCK_BUSY";
- case PAM_AUTHTOK_DISABLE_AGING:
- return "PAM_AUTHTOK_DISABLE_AGING";
- case PAM_TRY_AGAIN:
- return "PAM_TRY_AGAIN";
- case PAM_IGNORE:
- return "PAM_IGNORE";
- case PAM_ABORT:
- return "PAM_ABORT";
- case PAM_AUTHTOK_EXPIRED:
- return "PAM_AUTHTOK_EXPIRED";
-#ifdef PAM_MODULE_UNKNOWN
- case PAM_MODULE_UNKNOWN:
- return "PAM_MODULE_UNKNOWN";
-#endif
-#ifdef PAM_BAD_ITEM
- case PAM_BAD_ITEM:
- return "PAM_BAD_ITEM";
-#endif
-#ifdef PAM_CONV_AGAIN
- case PAM_CONV_AGAIN:
- return "PAM_CONV_AGAIN";
-#endif
-#ifdef PAM_INCOMPLETE
- case PAM_INCOMPLETE:
- return "PAM_INCOMPLETE";
-#endif
- default:
- return NULL;
- }
-}
-
-#define _PAM_LOG_FUNCTION_ENTER(function, ctx) \
- do { \
- _pam_log_debug(ctx, LOG_DEBUG, "[pamh: %p] ENTER: " \
- function " (flags: 0x%04x)", ctx->pamh, ctx->flags); \
- _pam_log_state(ctx); \
- } while (0)
-
-#define _PAM_LOG_FUNCTION_LEAVE(function, ctx, retval) \
- do { \
- _pam_log_debug(ctx, LOG_DEBUG, "[pamh: %p] LEAVE: " \
- function " returning %d (%s)", ctx->pamh, retval, \
- _pam_error_code_str(retval)); \
- _pam_log_state(ctx); \
- } while (0)
-
-/* data tokens */
-
-#define MAX_PASSWD_TRIES 3
-
-#ifdef HAVE_GETTEXT
-static char initialized = 0;
-
-static inline void textdomain_init(void);
-static inline void textdomain_init(void)
-{
- if (!initialized) {
- bindtextdomain(MODULE_NAME, dyn_LOCALEDIR);
- initialized = 1;
- }
- return;
-}
-#endif
-
-
-/*
- * Work around the pam API that has functions with void ** as parameters
- * These lead to strict aliasing warnings with gcc.
- */
-static int _pam_get_item(const pam_handle_t *pamh,
- int item_type,
- const void *_item)
-{
- const void **item = (const void **)_item;
- return pam_get_item(pamh, item_type, item);
-}
-static int _pam_get_data(const pam_handle_t *pamh,
- const char *module_data_name,
- const void *_data)
-{
- const void **data = (const void **)_data;
- return pam_get_data(pamh, module_data_name, data);
-}
-
-/* some syslogging */
-
-#ifdef HAVE_PAM_VSYSLOG
-static void _pam_log_int(const pam_handle_t *pamh,
- int err,
- const char *format,
- va_list args)
-{
- pam_vsyslog(pamh, err, format, args);
-}
-#else
-static void _pam_log_int(const pam_handle_t *pamh,
- int err,
- const char *format,
- va_list args)
-{
- char *format2 = NULL;
- const char *service;
-
- _pam_get_item(pamh, PAM_SERVICE, &service);
-
- format2 = (char *)malloc(strlen(MODULE_NAME)+strlen(format)+strlen(service)+5);
- if (format2 == NULL) {
- /* what else todo ? */
- vsyslog(err, format, args);
- return;
- }
-
- sprintf(format2, "%s(%s): %s", MODULE_NAME, service, format);
- vsyslog(err, format2, args);
- SAFE_FREE(format2);
-}
-#endif /* HAVE_PAM_VSYSLOG */
-
-static bool _pam_log_is_silent(int ctrl)
-{
- return on(ctrl, WINBIND_SILENT);
-}
-
-static void _pam_log(struct pwb_context *r, int err, const char *format, ...) PRINTF_ATTRIBUTE(3,4);
-static void _pam_log(struct pwb_context *r, int err, const char *format, ...)
-{
- va_list args;
-
- if (_pam_log_is_silent(r->ctrl)) {
- return;
- }
-
- va_start(args, format);
- _pam_log_int(r->pamh, err, format, args);
- va_end(args);
-}
-static void __pam_log(const pam_handle_t *pamh, int ctrl, int err, const char *format, ...) PRINTF_ATTRIBUTE(4,5);
-static void __pam_log(const pam_handle_t *pamh, int ctrl, int err, const char *format, ...)
-{
- va_list args;
-
- if (_pam_log_is_silent(ctrl)) {
- return;
- }
-
- va_start(args, format);
- _pam_log_int(pamh, err, format, args);
- va_end(args);
-}
-
-static bool _pam_log_is_debug_enabled(int ctrl)
-{
- if (ctrl == -1) {
- return false;
- }
-
- if (_pam_log_is_silent(ctrl)) {
- return false;
- }
-
- if (!(ctrl & WINBIND_DEBUG_ARG)) {
- return false;
- }
-
- return true;
-}
-
-static bool _pam_log_is_debug_state_enabled(int ctrl)
-{
- if (!(ctrl & WINBIND_DEBUG_STATE)) {
- return false;
- }
-
- return _pam_log_is_debug_enabled(ctrl);
-}
-
-static void _pam_log_debug(struct pwb_context *r, int err, const char *format, ...) PRINTF_ATTRIBUTE(3,4);
-static void _pam_log_debug(struct pwb_context *r, int err, const char *format, ...)
-{
- va_list args;
-
- if (!_pam_log_is_debug_enabled(r->ctrl)) {
- return;
- }
-
- va_start(args, format);
- _pam_log_int(r->pamh, err, format, args);
- va_end(args);
-}
-static void __pam_log_debug(const pam_handle_t *pamh, int ctrl, int err, const char *format, ...) PRINTF_ATTRIBUTE(4,5);
-static void __pam_log_debug(const pam_handle_t *pamh, int ctrl, int err, const char *format, ...)
-{
- va_list args;
-
- if (!_pam_log_is_debug_enabled(ctrl)) {
- return;
- }
-
- va_start(args, format);
- _pam_log_int(pamh, err, format, args);
- va_end(args);
-}
-
-static void _pam_log_state_datum(struct pwb_context *ctx,
- int item_type,
- const char *key,
- int is_string)
-{
- const void *data = NULL;
- if (item_type != 0) {
- pam_get_item(ctx->pamh, item_type, &data);
- } else {
- pam_get_data(ctx->pamh, key, &data);
- }
- if (data != NULL) {
- const char *type = (item_type != 0) ? "ITEM" : "DATA";
- if (is_string != 0) {
- _pam_log_debug(ctx, LOG_DEBUG,
- "[pamh: %p] STATE: %s(%s) = \"%s\" (%p)",
- ctx->pamh, type, key, (const char *)data,
- data);
- } else {
- _pam_log_debug(ctx, LOG_DEBUG,
- "[pamh: %p] STATE: %s(%s) = %p",
- ctx->pamh, type, key, data);
- }
- }
-}
-
-#define _PAM_LOG_STATE_DATA_POINTER(ctx, module_data_name) \
- _pam_log_state_datum(ctx, 0, module_data_name, 0)
-
-#define _PAM_LOG_STATE_DATA_STRING(ctx, module_data_name) \
- _pam_log_state_datum(ctx, 0, module_data_name, 1)
-
-#define _PAM_LOG_STATE_ITEM_POINTER(ctx, item_type) \
- _pam_log_state_datum(ctx, item_type, #item_type, 0)
-
-#define _PAM_LOG_STATE_ITEM_STRING(ctx, item_type) \
- _pam_log_state_datum(ctx, item_type, #item_type, 1)
-
-#ifdef DEBUG_PASSWORD
-#define _LOG_PASSWORD_AS_STRING 1
-#else
-#define _LOG_PASSWORD_AS_STRING 0
-#endif
-
-#define _PAM_LOG_STATE_ITEM_PASSWORD(ctx, item_type) \
- _pam_log_state_datum(ctx, item_type, #item_type, \
- _LOG_PASSWORD_AS_STRING)
-
-static void _pam_log_state(struct pwb_context *ctx)
-{
- if (!_pam_log_is_debug_state_enabled(ctx->ctrl)) {
- return;
- }
-
- _PAM_LOG_STATE_ITEM_STRING(ctx, PAM_SERVICE);
- _PAM_LOG_STATE_ITEM_STRING(ctx, PAM_USER);
- _PAM_LOG_STATE_ITEM_STRING(ctx, PAM_TTY);
- _PAM_LOG_STATE_ITEM_STRING(ctx, PAM_RHOST);
- _PAM_LOG_STATE_ITEM_STRING(ctx, PAM_RUSER);
- _PAM_LOG_STATE_ITEM_PASSWORD(ctx, PAM_OLDAUTHTOK);
- _PAM_LOG_STATE_ITEM_PASSWORD(ctx, PAM_AUTHTOK);
- _PAM_LOG_STATE_ITEM_STRING(ctx, PAM_USER_PROMPT);
- _PAM_LOG_STATE_ITEM_POINTER(ctx, PAM_CONV);
-#ifdef PAM_FAIL_DELAY
- _PAM_LOG_STATE_ITEM_POINTER(ctx, PAM_FAIL_DELAY);
-#endif
-#ifdef PAM_REPOSITORY
- _PAM_LOG_STATE_ITEM_POINTER(ctx, PAM_REPOSITORY);
-#endif
-
- _PAM_LOG_STATE_DATA_STRING(ctx, PAM_WINBIND_HOMEDIR);
- _PAM_LOG_STATE_DATA_STRING(ctx, PAM_WINBIND_LOGONSCRIPT);
- _PAM_LOG_STATE_DATA_STRING(ctx, PAM_WINBIND_LOGONSERVER);
- _PAM_LOG_STATE_DATA_STRING(ctx, PAM_WINBIND_PROFILEPATH);
- _PAM_LOG_STATE_DATA_STRING(ctx,
- PAM_WINBIND_NEW_AUTHTOK_REQD);
- /* Use atoi to get PAM result code */
- _PAM_LOG_STATE_DATA_STRING(ctx,
- PAM_WINBIND_NEW_AUTHTOK_REQD_DURING_AUTH);
- _PAM_LOG_STATE_DATA_POINTER(ctx, PAM_WINBIND_PWD_LAST_SET);
-}
-
-static int _pam_parse(const pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv,
- dictionary **result_d)
-{
- int ctrl = 0;
- const char *config_file = NULL;
- int i;
- const char **v;
- dictionary *d = NULL;
-
- if (flags & PAM_SILENT) {
- ctrl |= WINBIND_SILENT;
- }
-
- for (i=argc,v=argv; i-- > 0; ++v) {
- if (!strncasecmp(*v, "config", strlen("config"))) {
- ctrl |= WINBIND_CONFIG_FILE;
- config_file = v[i];
- break;
- }
- }
-
- if (config_file == NULL) {
- config_file = PAM_WINBIND_CONFIG_FILE;
- }
-
- d = iniparser_load(config_file);
- if (d == NULL) {
- goto config_from_pam;
- }
-
- if (iniparser_getboolean(d, "global:debug", false)) {
- ctrl |= WINBIND_DEBUG_ARG;
- }
-
- if (iniparser_getboolean(d, "global:debug_state", false)) {
- ctrl |= WINBIND_DEBUG_STATE;
- }
-
- if (iniparser_getboolean(d, "global:cached_login", false)) {
- ctrl |= WINBIND_CACHED_LOGIN;
- }
-
- if (iniparser_getboolean(d, "global:krb5_auth", false)) {
- ctrl |= WINBIND_KRB5_AUTH;
- }
-
- if (iniparser_getboolean(d, "global:silent", false)) {
- ctrl |= WINBIND_SILENT;
- }
-
- if (iniparser_getstr(d, "global:krb5_ccache_type") != NULL) {
- ctrl |= WINBIND_KRB5_CCACHE_TYPE;
- }
-
- if ((iniparser_getstr(d, "global:require-membership-of") != NULL) ||
- (iniparser_getstr(d, "global:require_membership_of") != NULL)) {
- ctrl |= WINBIND_REQUIRED_MEMBERSHIP;
- }
-
- if (iniparser_getboolean(d, "global:try_first_pass", false)) {
- ctrl |= WINBIND_TRY_FIRST_PASS_ARG;
- }
-
- if (iniparser_getint(d, "global:warn_pwd_expire", 0)) {
- ctrl |= WINBIND_WARN_PWD_EXPIRE;
- }
-
- if (iniparser_getboolean(d, "global:mkhomedir", false)) {
- ctrl |= WINBIND_MKHOMEDIR;
- }
-
-config_from_pam:
- /* step through arguments */
- for (i=argc,v=argv; i-- > 0; ++v) {
-
- /* generic options */
- if (!strcmp(*v,"debug"))
- ctrl |= WINBIND_DEBUG_ARG;
- else if (!strcasecmp(*v, "debug_state"))
- ctrl |= WINBIND_DEBUG_STATE;
- else if (!strcasecmp(*v, "silent"))
- ctrl |= WINBIND_SILENT;
- else if (!strcasecmp(*v, "use_authtok"))
- ctrl |= WINBIND_USE_AUTHTOK_ARG;
- else if (!strcasecmp(*v, "use_first_pass"))
- ctrl |= WINBIND_USE_FIRST_PASS_ARG;
- else if (!strcasecmp(*v, "try_first_pass"))
- ctrl |= WINBIND_TRY_FIRST_PASS_ARG;
- else if (!strcasecmp(*v, "unknown_ok"))
- ctrl |= WINBIND_UNKNOWN_OK_ARG;
- else if (!strncasecmp(*v, "require_membership_of",
- strlen("require_membership_of")))
- ctrl |= WINBIND_REQUIRED_MEMBERSHIP;
- else if (!strncasecmp(*v, "require-membership-of",
- strlen("require-membership-of")))
- ctrl |= WINBIND_REQUIRED_MEMBERSHIP;
- else if (!strcasecmp(*v, "krb5_auth"))
- ctrl |= WINBIND_KRB5_AUTH;
- else if (!strncasecmp(*v, "krb5_ccache_type",
- strlen("krb5_ccache_type")))
- ctrl |= WINBIND_KRB5_CCACHE_TYPE;
- else if (!strcasecmp(*v, "cached_login"))
- ctrl |= WINBIND_CACHED_LOGIN;
- else if (!strcasecmp(*v, "mkhomedir"))
- ctrl |= WINBIND_MKHOMEDIR;
- else {
- __pam_log(pamh, ctrl, LOG_ERR,
- "pam_parse: unknown option: %s", *v);
- return -1;
- }
-
- }
-
- if (result_d) {
- *result_d = d;
- } else {
- if (d) {
- iniparser_freedict(d);
- }
- }
-
- return ctrl;
-};
-
-static int _pam_winbind_free_context(struct pwb_context *ctx)
-{
- if (!ctx) {
- return 0;
- }
-
- if (ctx->dict) {
- iniparser_freedict(ctx->dict);
- }
-
- return 0;
-}
-
-static int _pam_winbind_init_context(pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv,
- struct pwb_context **ctx_p)
-{
- struct pwb_context *r = NULL;
-
-#ifdef HAVE_GETTEXT
- textdomain_init();
-#endif
-
- r = TALLOC_ZERO_P(NULL, struct pwb_context);
- if (!r) {
- return PAM_BUF_ERR;
- }
-
- talloc_set_destructor(r, _pam_winbind_free_context);
-
- r->pamh = pamh;
- r->flags = flags;
- r->argc = argc;
- r->argv = argv;
- r->ctrl = _pam_parse(pamh, flags, argc, argv, &r->dict);
- if (r->ctrl == -1) {
- TALLOC_FREE(r);
- return PAM_SYSTEM_ERR;
- }
-
- *ctx_p = r;
-
- return PAM_SUCCESS;
-}
-
-static void _pam_winbind_cleanup_func(pam_handle_t *pamh,
- void *data,
- int error_status)
-{
- int ctrl = _pam_parse(pamh, 0, 0, NULL, NULL);
- if (_pam_log_is_debug_state_enabled(ctrl)) {
- __pam_log_debug(pamh, ctrl, LOG_DEBUG,
- "[pamh: %p] CLEAN: cleaning up PAM data %p "
- "(error_status = %d)", pamh, data,
- error_status);
- }
- TALLOC_FREE(data);
-}
-
-
-static const struct ntstatus_errors {
- const char *ntstatus_string;
- const char *error_string;
-} ntstatus_errors[] = {
- {"NT_STATUS_OK",
- N_("Success")},
- {"NT_STATUS_BACKUP_CONTROLLER",
- N_("No primary Domain Controler available")},
- {"NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND",
- N_("No domain controllers found")},
- {"NT_STATUS_NO_LOGON_SERVERS",
- N_("No logon servers")},
- {"NT_STATUS_PWD_TOO_SHORT",
- N_("Password too short")},
- {"NT_STATUS_PWD_TOO_RECENT",
- N_("The password of this user is too recent to change")},
- {"NT_STATUS_PWD_HISTORY_CONFLICT",
- N_("Password is already in password history")},
- {"NT_STATUS_PASSWORD_EXPIRED",
- N_("Your password has expired")},
- {"NT_STATUS_PASSWORD_MUST_CHANGE",
- N_("You need to change your password now")},
- {"NT_STATUS_INVALID_WORKSTATION",
- N_("You are not allowed to logon from this workstation")},
- {"NT_STATUS_INVALID_LOGON_HOURS",
- N_("You are not allowed to logon at this time")},
- {"NT_STATUS_ACCOUNT_EXPIRED",
- N_("Your account has expired. "
- "Please contact your System administrator")}, /* SCNR */
- {"NT_STATUS_ACCOUNT_DISABLED",
- N_("Your account is disabled. "
- "Please contact your System administrator")}, /* SCNR */
- {"NT_STATUS_ACCOUNT_LOCKED_OUT",
- N_("Your account has been locked. "
- "Please contact your System administrator")}, /* SCNR */
- {"NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT",
- N_("Invalid Trust Account")},
- {"NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT",
- N_("Invalid Trust Account")},
- {"NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT",
- N_("Invalid Trust Account")},
- {"NT_STATUS_ACCESS_DENIED",
- N_("Access is denied")},
- {NULL, NULL}
-};
-
-static const char *_get_ntstatus_error_string(const char *nt_status_string)
-{
- int i;
- for (i=0; ntstatus_errors[i].ntstatus_string != NULL; i++) {
- if (!strcasecmp(ntstatus_errors[i].ntstatus_string,
- nt_status_string)) {
- return _(ntstatus_errors[i].error_string);
- }
- }
- return NULL;
-}
-
-/* --- authentication management functions --- */
-
-/* Attempt a conversation */
-
-static int converse(const pam_handle_t *pamh,
- int nargs,
- struct pam_message **message,
- struct pam_response **response)
-{
- int retval;
- struct pam_conv *conv;
-
- retval = _pam_get_item(pamh, PAM_CONV, &conv);
- if (retval == PAM_SUCCESS) {
- retval = conv->conv(nargs,
- (const struct pam_message **)message,
- response, conv->appdata_ptr);
- }
-
- return retval; /* propagate error status */
-}
-
-
-static int _make_remark(struct pwb_context *ctx,
- int type,
- const char *text)
-{
- int retval = PAM_SUCCESS;
-
- struct pam_message *pmsg[1], msg[1];
- struct pam_response *resp;
-
- if (ctx->flags & WINBIND_SILENT) {
- return PAM_SUCCESS;
- }
-
- pmsg[0] = &msg[0];
- msg[0].msg = discard_const_p(char, text);
- msg[0].msg_style = type;
-
- resp = NULL;
- retval = converse(ctx->pamh, 1, pmsg, &resp);
-
- if (resp) {
- _pam_drop_reply(resp, 1);
- }
- return retval;
-}
-
-static int _make_remark_v(struct pwb_context *ctx,
- int type,
- const char *format,
- va_list args)
-{
- char *var;
- int ret;
-
- ret = vasprintf(&var, format, args);
- if (ret < 0) {
- _pam_log(ctx, LOG_ERR, "memory allocation failure");
- return ret;
- }
-
- ret = _make_remark(ctx, type, var);
- SAFE_FREE(var);
- return ret;
-}
-
-static int _make_remark_format(struct pwb_context *ctx, int type, const char *format, ...) PRINTF_ATTRIBUTE(3,4);
-static int _make_remark_format(struct pwb_context *ctx, int type, const char *format, ...)
-{
- int ret;
- va_list args;
-
- va_start(args, format);
- ret = _make_remark_v(ctx, type, format, args);
- va_end(args);
- return ret;
-}
-
-static int pam_winbind_request_log(struct pwb_context *ctx,
- int retval,
- const char *user,
- const char *fn)
-{
- switch (retval) {
- case PAM_AUTH_ERR:
- /* incorrect password */
- _pam_log(ctx, LOG_WARNING, "user '%s' denied access "
- "(incorrect password or invalid membership)", user);
- return retval;
- case PAM_ACCT_EXPIRED:
- /* account expired */
- _pam_log(ctx, LOG_WARNING, "user '%s' account expired",
- user);
- return retval;
- case PAM_AUTHTOK_EXPIRED:
- /* password expired */
- _pam_log(ctx, LOG_WARNING, "user '%s' password expired",
- user);
- return retval;
- case PAM_NEW_AUTHTOK_REQD:
- /* new password required */
- _pam_log(ctx, LOG_WARNING, "user '%s' new password "
- "required", user);
- return retval;
- case PAM_USER_UNKNOWN:
- /* the user does not exist */
- _pam_log_debug(ctx, LOG_NOTICE, "user '%s' not found",
- user);
- if (ctx->ctrl & WINBIND_UNKNOWN_OK_ARG) {
- return PAM_IGNORE;
- }
- return retval;
- case PAM_SUCCESS:
- /* Otherwise, the authentication looked good */
- if (strcmp(fn, "wbcLogonUser") == 0) {
- _pam_log(ctx, LOG_NOTICE,
- "user '%s' granted access", user);
- } else {
- _pam_log(ctx, LOG_NOTICE,
- "user '%s' OK", user);
- }
- return retval;
- default:
- /* we don't know anything about this return value */
- _pam_log(ctx, LOG_ERR,
- "internal module error (retval = %s(%d), user = '%s')",
- _pam_error_code_str(retval), retval, user);
- return retval;
- }
-}
-
-static int wbc_auth_error_to_pam_error(struct pwb_context *ctx,
- struct wbcAuthErrorInfo *e,
- wbcErr status,
- const char *username,
- const char *fn)
-{
- int ret = PAM_AUTH_ERR;
-
- if (WBC_ERROR_IS_OK(status)) {
- _pam_log_debug(ctx, LOG_DEBUG, "request %s succeeded",
- fn);
- ret = PAM_SUCCESS;
- return pam_winbind_request_log(ctx, ret, username, fn);
- }
-
- if (e) {
- if (e->pam_error != PAM_SUCCESS) {
- _pam_log(ctx, LOG_ERR,
- "request %s failed: %s, "
- "PAM error: %s (%d), NTSTATUS: %s, "
- "Error message was: %s",
- fn,
- wbcErrorString(status),
- _pam_error_code_str(e->pam_error),
- e->pam_error,
- e->nt_string,
- e->display_string);
- ret = e->pam_error;
- return pam_winbind_request_log(ctx, ret, username, fn);
- }
-
- _pam_log(ctx, LOG_ERR, "request %s failed, but PAM error 0!", fn);
-
- ret = PAM_SERVICE_ERR;
- return pam_winbind_request_log(ctx, ret, username, fn);
- }
-
- ret = wbc_error_to_pam_error(status);
- return pam_winbind_request_log(ctx, ret, username, fn);
-}
-
-
-/**
- * send a password expiry message if required
- *
- * @param ctx PAM winbind context.
- * @param next_change expected (calculated) next expiry date.
- * @param already_expired pointer to a boolean to indicate if the password is
- * already expired.
- *
- * @return boolean Returns true if message has been sent, false if not.
- */
-
-static bool _pam_send_password_expiry_message(struct pwb_context *ctx,
- time_t next_change,
- time_t now,
- int warn_pwd_expire,
- bool *already_expired)
-{
- int days = 0;
- struct tm tm_now, tm_next_change;
-
- if (already_expired) {
- *already_expired = false;
- }
-
- if (next_change <= now) {
- PAM_WB_REMARK_DIRECT(ctx, "NT_STATUS_PASSWORD_EXPIRED");
- if (already_expired) {
- *already_expired = true;
- }
- return true;
- }
-
- if ((next_change < 0) ||
- (next_change > now + warn_pwd_expire * SECONDS_PER_DAY)) {
- return false;
- }
-
- if ((localtime_r(&now, &tm_now) == NULL) ||
- (localtime_r(&next_change, &tm_next_change) == NULL)) {
- return false;
- }
-
- days = (tm_next_change.tm_yday+tm_next_change.tm_year*365) -
- (tm_now.tm_yday+tm_now.tm_year*365);
-
- if (days == 0) {
- _make_remark(ctx, PAM_TEXT_INFO,
- _("Your password expires today"));
- return true;
- }
-
- if (days > 0 && days < warn_pwd_expire) {
- _make_remark_format(ctx, PAM_TEXT_INFO,
- _("Your password will expire in %d %s"),
- days, (days > 1) ? _("days"):_("day"));
- return true;
- }
-
- return false;
-}
-
-/**
- * Send a warning if the password expires in the near future
- *
- * @param ctx PAM winbind context.
- * @param response The full authentication response structure.
- * @param already_expired boolean, is the pwd already expired?
- *
- * @return void.
- */
-
-static void _pam_warn_password_expiry(struct pwb_context *ctx,
- const struct wbcAuthUserInfo *info,
- const struct wbcUserPasswordPolicyInfo *policy,
- int warn_pwd_expire,
- bool *already_expired)
-{
- time_t now = time(NULL);
- time_t next_change = 0;
-
- if (!info || !policy) {
- return;
- }
-
- if (already_expired) {
- *already_expired = false;
- }
-
- /* accounts with WBC_ACB_PWNOEXP set never receive a warning */
- if (info->acct_flags & WBC_ACB_PWNOEXP) {
- return;
- }
-
- /* no point in sending a warning if this is a grace logon */
- if (PAM_WB_GRACE_LOGON(info->user_flags)) {
- return;
- }
-
- /* check if the info3 must change timestamp has been set */
- next_change = info->pass_must_change_time;
-
- if (_pam_send_password_expiry_message(ctx, next_change, now,
- warn_pwd_expire,
- already_expired)) {
- return;
- }
-
- /* now check for the global password policy */
- /* good catch from Ralf Haferkamp: an expiry of "never" is translated
- * to -1 */
- if (policy->expire <= 0) {
- return;
- }
-
- next_change = info->pass_last_set_time + policy->expire;
-
- if (_pam_send_password_expiry_message(ctx, next_change, now,
- warn_pwd_expire,
- already_expired)) {
- return;
- }
-
- /* no warning sent */
-}
-
-#define IS_SID_STRING(name) (strncmp("S-", name, 2) == 0)
-
-/**
- * Append a string, making sure not to overflow and to always return a
- * NULL-terminated string.
- *
- * @param dest Destination string buffer (must already be NULL-terminated).
- * @param src Source string buffer.
- * @param dest_buffer_size Size of dest buffer in bytes.
- *
- * @return false if dest buffer is not big enough (no bytes copied), true on
- * success.
- */
-
-static bool safe_append_string(char *dest,
- const char *src,
- int dest_buffer_size)
-{
- int dest_length = strlen(dest);
- int src_length = strlen(src);
-
- if (dest_length + src_length + 1 > dest_buffer_size) {
- return false;
- }
-
- memcpy(dest + dest_length, src, src_length + 1);
- return true;
-}
-
-/**
- * Convert a names into a SID string, appending it to a buffer.
- *
- * @param ctx PAM winbind context.
- * @param user User in PAM request.
- * @param name Name to convert.
- * @param sid_list_buffer Where to append the string sid.
- * @param sid_list_buffer Size of sid_list_buffer (in bytes).
- *
- * @return false on failure, true on success.
- */
-static bool winbind_name_to_sid_string(struct pwb_context *ctx,
- const char *user,
- const char *name,
- char *sid_list_buffer,
- int sid_list_buffer_size)
-{
- const char* sid_string;
-
- /* lookup name? */
- if (IS_SID_STRING(name)) {
- sid_string = name;
- } else {
- wbcErr wbc_status;
- struct wbcDomainSid sid;
- enum wbcSidType type;
- char *sid_str;
-
- _pam_log_debug(ctx, LOG_DEBUG,
- "no sid given, looking up: %s\n", name);
-
- wbc_status = wbcLookupName("", name, &sid, &type);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- _pam_log(ctx, LOG_INFO,
- "could not lookup name: %s\n", name);
- return false;
- }
-
- wbc_status = wbcSidToString(&sid, &sid_str);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- wbcFreeMemory(sid_str);
- sid_string = sid_str;
- }
-
- if (!safe_append_string(sid_list_buffer, sid_string,
- sid_list_buffer_size)) {
- return false;
- }
-
- return true;
-}
-
-/**
- * Convert a list of names into a list of sids.
- *
- * @param ctx PAM winbind context.
- * @param user User in PAM request.
- * @param name_list List of names or string sids, separated by commas.
- * @param sid_list_buffer Where to put the list of string sids.
- * @param sid_list_buffer Size of sid_list_buffer (in bytes).
- *
- * @return false on failure, true on success.
- */
-static bool winbind_name_list_to_sid_string_list(struct pwb_context *ctx,
- const char *user,
- const char *name_list,
- char *sid_list_buffer,
- int sid_list_buffer_size)
-{
- bool result = false;
- char *current_name = NULL;
- const char *search_location;
- const char *comma;
-
- if (sid_list_buffer_size > 0) {
- sid_list_buffer[0] = 0;
- }
-
- search_location = name_list;
- while ((comma = strstr(search_location, ",")) != NULL) {
- current_name = strndup(search_location,
- comma - search_location);
- if (NULL == current_name) {
- goto out;
- }
-
- if (!winbind_name_to_sid_string(ctx, user,
- current_name,
- sid_list_buffer,
- sid_list_buffer_size)) {
- goto out;
- }
-
- SAFE_FREE(current_name);
-
- if (!safe_append_string(sid_list_buffer, ",",
- sid_list_buffer_size)) {
- goto out;
- }
-
- search_location = comma + 1;
- }
-
- if (!winbind_name_to_sid_string(ctx, user, search_location,
- sid_list_buffer,
- sid_list_buffer_size)) {
- goto out;
- }
-
- result = true;
-
-out:
- SAFE_FREE(current_name);
- return result;
-}
-
-/**
- * put krb5ccname variable into environment
- *
- * @param ctx PAM winbind context.
- * @param krb5ccname env variable retrieved from winbindd.
- *
- * @return void.
- */
-
-static void _pam_setup_krb5_env(struct pwb_context *ctx,
- struct wbcLogonUserInfo *info)
-{
- char var[PATH_MAX];
- int ret;
- uint32_t i;
- const char *krb5ccname = NULL;
-
- if (off(ctx->ctrl, WINBIND_KRB5_AUTH)) {
- return;
- }
-
- if (!info) {
- return;
- }
-
- for (i=0; i < info->num_blobs; i++) {
- if (strcasecmp(info->blobs[i].name, "krb5ccname") == 0) {
- krb5ccname = (const char *)info->blobs[i].blob.data;
- break;
- }
- }
-
- if (!krb5ccname || (strlen(krb5ccname) == 0)) {
- return;
- }
-
- _pam_log_debug(ctx, LOG_DEBUG,
- "request returned KRB5CCNAME: %s", krb5ccname);
-
- if (snprintf(var, sizeof(var), "KRB5CCNAME=%s", krb5ccname) == -1) {
- return;
- }
-
- ret = pam_putenv(ctx->pamh, var);
- if (ret) {
- _pam_log(ctx, LOG_ERR,
- "failed to set KRB5CCNAME to %s: %s",
- var, pam_strerror(ctx->pamh, ret));
- }
-}
-
-/**
- * Copy unix username if available (further processed in PAM).
- *
- * @param ctx PAM winbind context
- * @param user_ret A pointer that holds a pointer to a string
- * @param unix_username A username
- *
- * @return void.
- */
-
-static void _pam_setup_unix_username(struct pwb_context *ctx,
- char **user_ret,
- struct wbcLogonUserInfo *info)
-{
- const char *unix_username = NULL;
- uint32_t i;
-
- if (!user_ret || !info) {
- return;
- }
-
- for (i=0; i < info->num_blobs; i++) {
- if (strcasecmp(info->blobs[i].name, "unix_username") == 0) {
- unix_username = (const char *)info->blobs[i].blob.data;
- break;
- }
- }
-
- if (!unix_username || !unix_username[0]) {
- return;
- }
-
- *user_ret = strdup(unix_username);
-}
-
-/**
- * Set string into the PAM stack.
- *
- * @param ctx PAM winbind context.
- * @param data_name Key name for pam_set_data.
- * @param value String value.
- *
- * @return void.
- */
-
-static void _pam_set_data_string(struct pwb_context *ctx,
- const char *data_name,
- const char *value)
-{
- int ret;
-
- if (!data_name || !value || (strlen(data_name) == 0) ||
- (strlen(value) == 0)) {
- return;
- }
-
- ret = pam_set_data(ctx->pamh, data_name, talloc_strdup(NULL, value),
- _pam_winbind_cleanup_func);
- if (ret) {
- _pam_log_debug(ctx, LOG_DEBUG,
- "Could not set data %s: %s\n",
- data_name, pam_strerror(ctx->pamh, ret));
- }
-}
-
-/**
- * Set info3 strings into the PAM stack.
- *
- * @param ctx PAM winbind context.
- * @param data_name Key name for pam_set_data.
- * @param value String value.
- *
- * @return void.
- */
-
-static void _pam_set_data_info3(struct pwb_context *ctx,
- const struct wbcAuthUserInfo *info)
-{
- _pam_set_data_string(ctx, PAM_WINBIND_HOMEDIR,
- info->home_directory);
- _pam_set_data_string(ctx, PAM_WINBIND_LOGONSCRIPT,
- info->logon_script);
- _pam_set_data_string(ctx, PAM_WINBIND_LOGONSERVER,
- info->logon_server);
- _pam_set_data_string(ctx, PAM_WINBIND_PROFILEPATH,
- info->profile_path);
-}
-
-/**
- * Free info3 strings in the PAM stack.
- *
- * @param pamh PAM handle
- *
- * @return void.
- */
-
-static void _pam_free_data_info3(pam_handle_t *pamh)
-{
- pam_set_data(pamh, PAM_WINBIND_HOMEDIR, NULL, NULL);
- pam_set_data(pamh, PAM_WINBIND_LOGONSCRIPT, NULL, NULL);
- pam_set_data(pamh, PAM_WINBIND_LOGONSERVER, NULL, NULL);
- pam_set_data(pamh, PAM_WINBIND_PROFILEPATH, NULL, NULL);
-}
-
-/**
- * Send PAM_ERROR_MSG for cached or grace logons.
- *
- * @param ctx PAM winbind context.
- * @param username User in PAM request.
- * @param info3_user_flgs Info3 flags containing logon type bits.
- *
- * @return void.
- */
-
-static void _pam_warn_logon_type(struct pwb_context *ctx,
- const char *username,
- uint32_t info3_user_flgs)
-{
- /* inform about logon type */
- if (PAM_WB_GRACE_LOGON(info3_user_flgs)) {
-
- _make_remark(ctx, PAM_ERROR_MSG,
- _("Grace login. "
- "Please change your password as soon you're "
- "online again"));
- _pam_log_debug(ctx, LOG_DEBUG,
- "User %s logged on using grace logon\n",
- username);
-
- } else if (PAM_WB_CACHED_LOGON(info3_user_flgs)) {
-
- _make_remark(ctx, PAM_ERROR_MSG,
- _("Domain Controller unreachable, "
- "using cached credentials instead. "
- "Network resources may be unavailable"));
- _pam_log_debug(ctx, LOG_DEBUG,
- "User %s logged on using cached credentials\n",
- username);
- }
-}
-
-/**
- * Send PAM_ERROR_MSG for krb5 errors.
- *
- * @param ctx PAM winbind context.
- * @param username User in PAM request.
- * @param info3_user_flgs Info3 flags containing logon type bits.
- *
- * @return void.
- */
-
-static void _pam_warn_krb5_failure(struct pwb_context *ctx,
- const char *username,
- uint32_t info3_user_flgs)
-{
- if (PAM_WB_KRB5_CLOCK_SKEW(info3_user_flgs)) {
- _make_remark(ctx, PAM_ERROR_MSG,
- _("Failed to establish your Kerberos Ticket cache "
- "due time differences\n"
- "with the domain controller. "
- "Please verify the system time.\n"));
- _pam_log_debug(ctx, LOG_DEBUG,
- "User %s: Clock skew when getting Krb5 TGT\n",
- username);
- }
-}
-
-static bool _pam_check_remark_auth_err(struct pwb_context *ctx,
- const struct wbcAuthErrorInfo *e,
- const char *nt_status_string,
- int *pam_error)
-{
- const char *ntstatus = NULL;
- const char *error_string = NULL;
-
- if (!e || !pam_error) {
- return false;
- }
-
- ntstatus = e->nt_string;
- if (!ntstatus) {
- return false;
- }
-
- if (strcasecmp(ntstatus, nt_status_string) == 0) {
-
- error_string = _get_ntstatus_error_string(nt_status_string);
- if (error_string) {
- _make_remark(ctx, PAM_ERROR_MSG, error_string);
- *pam_error = e->pam_error;
- return true;
- }
-
- if (e->display_string) {
- _make_remark(ctx, PAM_ERROR_MSG, e->display_string);
- *pam_error = e->pam_error;
- return true;
- }
-
- _make_remark(ctx, PAM_ERROR_MSG, nt_status_string);
- *pam_error = e->pam_error;
-
- return true;
- }
-
- return false;
-};
-
-/**
- * Compose Password Restriction String for a PAM_ERROR_MSG conversation.
- *
- * @param i The wbcUserPasswordPolicyInfo struct.
- *
- * @return string (caller needs to talloc_free).
- */
-
-static char *_pam_compose_pwd_restriction_string(struct pwb_context *ctx,
- struct wbcUserPasswordPolicyInfo *i)
-{
- char *str = NULL;
-
- if (!i) {
- goto failed;
- }
-
- str = talloc_asprintf(ctx, _("Your password "));
- if (!str) {
- goto failed;
- }
-
- if (i->min_length_password > 0) {
- str = talloc_asprintf_append(str,
- _("must be at least %d characters; "),
- i->min_length_password);
- if (!str) {
- goto failed;
- }
- }
-
- if (i->password_history > 0) {
- str = talloc_asprintf_append(str,
- _("cannot repeat any of your previous %d "
- "passwords; "),
- i->password_history);
- if (!str) {
- goto failed;
- }
- }
-
- if (i->password_properties & WBC_DOMAIN_PASSWORD_COMPLEX) {
- str = talloc_asprintf_append(str,
- _("must contain capitals, numerals "
- "or punctuation; "
- "and cannot contain your account "
- "or full name; "));
- if (!str) {
- goto failed;
- }
- }
-
- str = talloc_asprintf_append(str,
- _("Please type a different password. "
- "Type a password which meets these requirements in "
- "both text boxes."));
- if (!str) {
- goto failed;
- }
-
- return str;
-
- failed:
- TALLOC_FREE(str);
- return NULL;
-}
-
-static int _pam_create_homedir(struct pwb_context *ctx,
- const char *dirname,
- mode_t mode)
-{
- struct stat sbuf;
-
- if (stat(dirname, &sbuf) == 0) {
- return PAM_SUCCESS;
- }
-
- if (mkdir(dirname, mode) != 0) {
-
- _make_remark_format(ctx, PAM_TEXT_INFO,
- _("Creating directory: %s failed: %s"),
- dirname, strerror(errno));
- _pam_log(ctx, LOG_ERR, "could not create dir: %s (%s)",
- dirname, strerror(errno));
- return PAM_PERM_DENIED;
- }
-
- return PAM_SUCCESS;
-}
-
-static int _pam_chown_homedir(struct pwb_context *ctx,
- const char *dirname,
- uid_t uid,
- gid_t gid)
-{
- if (chown(dirname, uid, gid) != 0) {
- _pam_log(ctx, LOG_ERR, "failed to chown user homedir: %s (%s)",
- dirname, strerror(errno));
- return PAM_PERM_DENIED;
- }
-
- return PAM_SUCCESS;
-}
-
-static int _pam_mkhomedir(struct pwb_context *ctx)
-{
- struct passwd *pwd = NULL;
- char *token = NULL;
- char *create_dir = NULL;
- char *user_dir = NULL;
- int ret;
- const char *username;
- mode_t mode = 0700;
- char *safe_ptr = NULL;
- char *p = NULL;
-
- /* Get the username */
- ret = pam_get_user(ctx->pamh, &username, NULL);
- if ((ret != PAM_SUCCESS) || (!username)) {
- _pam_log_debug(ctx, LOG_DEBUG, "can not get the username");
- return PAM_SERVICE_ERR;
- }
-
- pwd = getpwnam(username);
- if (pwd == NULL) {
- _pam_log_debug(ctx, LOG_DEBUG, "can not get the username");
- return PAM_USER_UNKNOWN;
- }
- _pam_log_debug(ctx, LOG_DEBUG, "homedir is: %s", pwd->pw_dir);
-
- ret = _pam_create_homedir(ctx, pwd->pw_dir, 0700);
- if (ret == PAM_SUCCESS) {
- ret = _pam_chown_homedir(ctx, pwd->pw_dir,
- pwd->pw_uid,
- pwd->pw_gid);
- }
-
- if (ret == PAM_SUCCESS) {
- return ret;
- }
-
- /* maybe we need to create parent dirs */
- create_dir = talloc_strdup(ctx, "/");
- if (!create_dir) {
- return PAM_BUF_ERR;
- }
-
- /* find final directory */
- user_dir = strrchr(pwd->pw_dir, '/');
- if (!user_dir) {
- return PAM_BUF_ERR;
- }
- user_dir++;
-
- _pam_log(ctx, LOG_DEBUG, "final directory: %s", user_dir);
-
- p = pwd->pw_dir;
-
- while ((token = strtok_r(p, "/", &safe_ptr)) != NULL) {
-
- mode = 0755;
-
- p = NULL;
-
- _pam_log_debug(ctx, LOG_DEBUG, "token is %s", token);
-
- create_dir = talloc_asprintf_append(create_dir, "%s/", token);
- if (!create_dir) {
- return PAM_BUF_ERR;
- }
- _pam_log_debug(ctx, LOG_DEBUG, "current_dir is %s", create_dir);
-
- if (strcmp(token, user_dir) == 0) {
- _pam_log_debug(ctx, LOG_DEBUG, "assuming last directory: %s", token);
- mode = 0700;
- }
-
- ret = _pam_create_homedir(ctx, create_dir, mode);
- if (ret) {
- return ret;
- }
- }
-
- return _pam_chown_homedir(ctx, create_dir,
- pwd->pw_uid,
- pwd->pw_gid);
-}
-
-/* talk to winbindd */
-static int winbind_auth_request(struct pwb_context *ctx,
- const char *user,
- const char *pass,
- const char *member,
- const char *cctype,
- const int warn_pwd_expire,
- struct wbcAuthErrorInfo **p_error,
- struct wbcLogonUserInfo **p_info,
- struct wbcUserPasswordPolicyInfo **p_policy,
- time_t *pwd_last_set,
- char **user_ret)
-{
- wbcErr wbc_status;
-
- struct wbcLogonUserParams logon;
- char membership_of[1024];
- uid_t user_uid = -1;
- uint32_t flags = WBFLAG_PAM_INFO3_TEXT |
- WBFLAG_PAM_GET_PWD_POLICY;
-
- struct wbcLogonUserInfo *info = NULL;
- struct wbcAuthUserInfo *user_info = NULL;
- struct wbcAuthErrorInfo *error = NULL;
- struct wbcUserPasswordPolicyInfo *policy = NULL;
-
- int ret = PAM_AUTH_ERR;
- int i;
- const char *codes[] = {
- "NT_STATUS_PASSWORD_EXPIRED",
- "NT_STATUS_PASSWORD_MUST_CHANGE",
- "NT_STATUS_INVALID_WORKSTATION",
- "NT_STATUS_INVALID_LOGON_HOURS",
- "NT_STATUS_ACCOUNT_EXPIRED",
- "NT_STATUS_ACCOUNT_DISABLED",
- "NT_STATUS_ACCOUNT_LOCKED_OUT",
- "NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT",
- "NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT",
- "NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT",
- "NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND",
- "NT_STATUS_NO_LOGON_SERVERS",
- "NT_STATUS_WRONG_PASSWORD",
- "NT_STATUS_ACCESS_DENIED"
- };
-
- if (pwd_last_set) {
- *pwd_last_set = 0;
- }
-
- /* Krb5 auth always has to go against the KDC of the user's realm */
-
- if (ctx->ctrl & WINBIND_KRB5_AUTH) {
- flags |= WBFLAG_PAM_CONTACT_TRUSTDOM;
- }
-
- if (ctx->ctrl & (WINBIND_KRB5_AUTH|WINBIND_CACHED_LOGIN)) {
- struct passwd *pwd = NULL;
-
- pwd = getpwnam(user);
- if (pwd == NULL) {
- return PAM_USER_UNKNOWN;
- }
- user_uid = pwd->pw_uid;
- }
-
- if (ctx->ctrl & WINBIND_KRB5_AUTH) {
-
- _pam_log_debug(ctx, LOG_DEBUG,
- "enabling krb5 login flag\n");
-
- flags |= WBFLAG_PAM_KRB5 |
- WBFLAG_PAM_FALLBACK_AFTER_KRB5;
- }
-
- if (ctx->ctrl & WINBIND_CACHED_LOGIN) {
- _pam_log_debug(ctx, LOG_DEBUG,
- "enabling cached login flag\n");
- flags |= WBFLAG_PAM_CACHED_LOGIN;
- }
-
- if (user_ret) {
- *user_ret = NULL;
- flags |= WBFLAG_PAM_UNIX_NAME;
- }
-
- if (cctype != NULL) {
- _pam_log_debug(ctx, LOG_DEBUG,
- "enabling request for a %s krb5 ccache\n",
- cctype);
- }
-
- if (member != NULL) {
-
- ZERO_STRUCT(membership_of);
-
- if (!winbind_name_list_to_sid_string_list(ctx, user, member,
- membership_of,
- sizeof(membership_of))) {
- _pam_log_debug(ctx, LOG_ERR,
- "failed to serialize membership of sid "
- "\"%s\"\n", member);
- return PAM_AUTH_ERR;
- }
- }
-
- ZERO_STRUCT(logon);
-
- logon.username = user;
- logon.password = pass;
-
- if (cctype) {
- wbc_status = wbcAddNamedBlob(&logon.num_blobs,
- &logon.blobs,
- "krb5_cc_type",
- 0,
- (uint8_t *)cctype,
- strlen(cctype)+1);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- goto done;
- }
- }
-
- wbc_status = wbcAddNamedBlob(&logon.num_blobs,
- &logon.blobs,
- "flags",
- 0,
- (uint8_t *)&flags,
- sizeof(flags));
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- goto done;
- }
-
- wbc_status = wbcAddNamedBlob(&logon.num_blobs,
- &logon.blobs,
- "user_uid",
- 0,
- (uint8_t *)&user_uid,
- sizeof(user_uid));
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- goto done;
- }
-
- if (member) {
- wbc_status = wbcAddNamedBlob(&logon.num_blobs,
- &logon.blobs,
- "membership_of",
- 0,
- (uint8_t *)membership_of,
- sizeof(membership_of));
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- goto done;
- }
- }
-
- wbc_status = wbcLogonUser(&logon, &info, &error, &policy);
- ret = wbc_auth_error_to_pam_error(ctx, error, wbc_status,
- user, "wbcLogonUser");
- wbcFreeMemory(logon.blobs);
- logon.blobs = NULL;
-
- if (info && info->info) {
- user_info = info->info;
- }
-
- if (pwd_last_set && user_info) {
- *pwd_last_set = user_info->pass_last_set_time;
- }
-
- if (p_info && info) {
- *p_info = info;
- }
-
- if (p_policy && policy) {
- *p_policy = policy;
- }
-
- if (p_error && error) {
- /* We want to process the error in the caller. */
- *p_error = error;
- return ret;
- }
-
- for (i=0; i<ARRAY_SIZE(codes); i++) {
- int _ret = ret;
- if (_pam_check_remark_auth_err(ctx, error, codes[i], &_ret)) {
- ret = _ret;
- goto done;
- }
- }
-
- if ((ret == PAM_SUCCESS) && user_info && policy && info) {
-
- bool already_expired = false;
-
- /* warn a user if the password is about to expire soon */
- _pam_warn_password_expiry(ctx, user_info, policy,
- warn_pwd_expire,
- &already_expired);
-
- if (already_expired == true) {
-
- SMB_TIME_T last_set = user_info->pass_last_set_time;
-
- _pam_log_debug(ctx, LOG_DEBUG,
- "Password has expired "
- "(Password was last set: %lld, "
- "the policy says it should expire here "
- "%lld (now it's: %lu))\n",
- (long long int)last_set,
- (long long int)last_set +
- policy->expire,
- time(NULL));
-
- return PAM_AUTHTOK_EXPIRED;
- }
-
- /* inform about logon type */
- _pam_warn_logon_type(ctx, user, user_info->user_flags);
-
- /* inform about krb5 failures */
- _pam_warn_krb5_failure(ctx, user, user_info->user_flags);
-
- /* set some info3 info for other modules in the stack */
- _pam_set_data_info3(ctx, user_info);
-
- /* put krb5ccname into env */
- _pam_setup_krb5_env(ctx, info);
-
- /* If winbindd returned a username, return the pointer to it
- * here. */
- _pam_setup_unix_username(ctx, user_ret, info);
- }
-
- done:
- if (logon.blobs) {
- wbcFreeMemory(logon.blobs);
- }
- if (info && info->blobs) {
- wbcFreeMemory(info->blobs);
- }
- if (error && !p_error) {
- wbcFreeMemory(error);
- }
- if (info && !p_info) {
- wbcFreeMemory(info);
- }
- if (policy && !p_policy) {
- wbcFreeMemory(policy);
- }
-
- return ret;
-}
-
-/* talk to winbindd */
-static int winbind_chauthtok_request(struct pwb_context *ctx,
- const char *user,
- const char *oldpass,
- const char *newpass,
- time_t pwd_last_set)
-{
- wbcErr wbc_status;
- struct wbcChangePasswordParams params;
- struct wbcAuthErrorInfo *error = NULL;
- struct wbcUserPasswordPolicyInfo *policy = NULL;
- enum wbcPasswordChangeRejectReason reject_reason = -1;
- uint32_t flags = 0;
-
- int i;
- const char *codes[] = {
- "NT_STATUS_BACKUP_CONTROLLER",
- "NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND",
- "NT_STATUS_NO_LOGON_SERVERS",
- "NT_STATUS_ACCESS_DENIED",
- "NT_STATUS_PWD_TOO_SHORT", /* TODO: tell the min pwd length ? */
- "NT_STATUS_PWD_TOO_RECENT", /* TODO: tell the minage ? */
- "NT_STATUS_PWD_HISTORY_CONFLICT" /* TODO: tell the history length ? */
- };
- int ret = PAM_AUTH_ERR;
-
- ZERO_STRUCT(params);
-
- if (ctx->ctrl & WINBIND_KRB5_AUTH) {
- flags |= WBFLAG_PAM_KRB5 |
- WBFLAG_PAM_CONTACT_TRUSTDOM;
- }
-
- if (ctx->ctrl & WINBIND_CACHED_LOGIN) {
- flags |= WBFLAG_PAM_CACHED_LOGIN;
- }
-
- params.account_name = user;
- params.level = WBC_AUTH_USER_LEVEL_PLAIN;
- params.old_password.plaintext = oldpass;
- params.new_password.plaintext = newpass;
- params.flags = flags;
-
- wbc_status = wbcChangeUserPasswordEx(&params, &error, &reject_reason, &policy);
- ret = wbc_auth_error_to_pam_error(ctx, error, wbc_status,
- user, "wbcChangeUserPasswordEx");
-
- if (WBC_ERROR_IS_OK(wbc_status)) {
- _pam_log(ctx, LOG_NOTICE,
- "user '%s' password changed", user);
- return PAM_SUCCESS;
- }
-
- if (!error) {
- wbcFreeMemory(policy);
- return ret;
- }
-
- for (i=0; i<ARRAY_SIZE(codes); i++) {
- int _ret = ret;
- if (_pam_check_remark_auth_err(ctx, error, codes[i], &_ret)) {
- ret = _ret;
- goto done;
- }
- }
-
- if (!strcasecmp(error->nt_string,
- "NT_STATUS_PASSWORD_RESTRICTION")) {
-
- char *pwd_restriction_string = NULL;
- SMB_TIME_T min_pwd_age = 0;
-
- if (policy) {
- min_pwd_age = policy->min_passwordage;
- }
-
- /* FIXME: avoid to send multiple PAM messages after another */
- switch (reject_reason) {
- case -1:
- break;
- case WBC_PWD_CHANGE_REJECT_OTHER:
- if ((min_pwd_age > 0) &&
- (pwd_last_set + min_pwd_age > time(NULL))) {
- PAM_WB_REMARK_DIRECT(ctx,
- "NT_STATUS_PWD_TOO_RECENT");
- }
- break;
- case WBC_PWD_CHANGE_REJECT_TOO_SHORT:
- PAM_WB_REMARK_DIRECT(ctx,
- "NT_STATUS_PWD_TOO_SHORT");
- break;
- case WBC_PWD_CHANGE_REJECT_IN_HISTORY:
- PAM_WB_REMARK_DIRECT(ctx,
- "NT_STATUS_PWD_HISTORY_CONFLICT");
- break;
- case WBC_PWD_CHANGE_REJECT_COMPLEXITY:
- _make_remark(ctx, PAM_ERROR_MSG,
- _("Password does not meet "
- "complexity requirements"));
- break;
- default:
- _pam_log_debug(ctx, LOG_DEBUG,
- "unknown password change "
- "reject reason: %d",
- reject_reason);
- break;
- }
-
- pwd_restriction_string =
- _pam_compose_pwd_restriction_string(ctx, policy);
- if (pwd_restriction_string) {
- _make_remark(ctx, PAM_ERROR_MSG,
- pwd_restriction_string);
- TALLOC_FREE(pwd_restriction_string);
- }
- }
- done:
- wbcFreeMemory(error);
- wbcFreeMemory(policy);
-
- return ret;
-}
-
-/*
- * Checks if a user has an account
- *
- * return values:
- * 1 = User not found
- * 0 = OK
- * -1 = System error
- */
-static int valid_user(struct pwb_context *ctx,
- const char *user)
-{
- /* check not only if the user is available over NSS calls, also make
- * sure it's really a winbind user, this is important when stacking PAM
- * modules in the 'account' or 'password' facility. */
-
- wbcErr wbc_status;
- struct passwd *pwd = NULL;
- struct passwd *wb_pwd = NULL;
-
- pwd = getpwnam(user);
- if (pwd == NULL) {
- return 1;
- }
-
- wbc_status = wbcGetpwnam(user, &wb_pwd);
- wbcFreeMemory(wb_pwd);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- _pam_log(ctx, LOG_DEBUG, "valid_user: wbcGetpwnam gave %s\n",
- wbcErrorString(wbc_status));
- }
-
- switch (wbc_status) {
- case WBC_ERR_UNKNOWN_USER:
- return 1;
- case WBC_ERR_SUCCESS:
- return 0;
- default:
- break;
- }
- return -1;
-}
-
-static char *_pam_delete(register char *xx)
-{
- _pam_overwrite(xx);
- _pam_drop(xx);
- return NULL;
-}
-
-/*
- * obtain a password from the user
- */
-
-static int _winbind_read_password(struct pwb_context *ctx,
- unsigned int ctrl,
- const char *comment,
- const char *prompt1,
- const char *prompt2,
- const char **pass)
-{
- int authtok_flag;
- int retval;
- const char *item;
- char *token;
-
- _pam_log(ctx, LOG_DEBUG, "getting password (0x%08x)", ctrl);
-
- /*
- * make sure nothing inappropriate gets returned
- */
-
- *pass = token = NULL;
-
- /*
- * which authentication token are we getting?
- */
-
- if (on(WINBIND__OLD_PASSWORD, ctrl)) {
- authtok_flag = PAM_OLDAUTHTOK;
- } else {
- authtok_flag = PAM_AUTHTOK;
- }
-
- /*
- * should we obtain the password from a PAM item ?
- */
-
- if (on(WINBIND_TRY_FIRST_PASS_ARG, ctrl) ||
- on(WINBIND_USE_FIRST_PASS_ARG, ctrl)) {
- retval = _pam_get_item(ctx->pamh, authtok_flag, &item);
- if (retval != PAM_SUCCESS) {
- /* very strange. */
- _pam_log(ctx, LOG_ALERT,
- "pam_get_item returned error "
- "to unix-read-password");
- return retval;
- } else if (item != NULL) { /* we have a password! */
- *pass = item;
- item = NULL;
- _pam_log(ctx, LOG_DEBUG,
- "pam_get_item returned a password");
- return PAM_SUCCESS;
- } else if (on(WINBIND_USE_FIRST_PASS_ARG, ctrl)) {
- return PAM_AUTHTOK_RECOVER_ERR; /* didn't work */
- } else if (on(WINBIND_USE_AUTHTOK_ARG, ctrl)
- && off(WINBIND__OLD_PASSWORD, ctrl)) {
- return PAM_AUTHTOK_RECOVER_ERR;
- }
- }
- /*
- * getting here implies we will have to get the password from the
- * user directly.
- */
-
- {
- struct pam_message msg[3], *pmsg[3];
- struct pam_response *resp;
- int i, replies;
-
- /* prepare to converse */
-
- if (comment != NULL && off(ctrl, WINBIND_SILENT)) {
- pmsg[0] = &msg[0];
- msg[0].msg_style = PAM_TEXT_INFO;
- msg[0].msg = discard_const_p(char, comment);
- i = 1;
- } else {
- i = 0;
- }
-
- pmsg[i] = &msg[i];
- msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
- msg[i++].msg = discard_const_p(char, prompt1);
- replies = 1;
-
- if (prompt2 != NULL) {
- pmsg[i] = &msg[i];
- msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
- msg[i++].msg = discard_const_p(char, prompt2);
- ++replies;
- }
- /* so call the conversation expecting i responses */
- resp = NULL;
- retval = converse(ctx->pamh, i, pmsg, &resp);
- if (resp == NULL) {
- if (retval == PAM_SUCCESS) {
- retval = PAM_AUTHTOK_RECOVER_ERR;
- }
- goto done;
- }
- if (retval != PAM_SUCCESS) {
- _pam_drop_reply(resp, i);
- goto done;
- }
-
- /* interpret the response */
-
- token = x_strdup(resp[i - replies].resp);
- if (!token) {
- _pam_log(ctx, LOG_NOTICE,
- "could not recover "
- "authentication token");
- retval = PAM_AUTHTOK_RECOVER_ERR;
- goto done;
- }
-
- if (replies == 2) {
- /* verify that password entered correctly */
- if (!resp[i - 1].resp ||
- strcmp(token, resp[i - 1].resp)) {
- _pam_delete(token); /* mistyped */
- retval = PAM_AUTHTOK_RECOVER_ERR;
- _make_remark(ctx, PAM_ERROR_MSG,
- MISTYPED_PASS);
- }
- }
-
- /*
- * tidy up the conversation (resp_retcode) is ignored
- * -- what is it for anyway? AGM
- */
- _pam_drop_reply(resp, i);
- }
-
- done:
- if (retval != PAM_SUCCESS) {
- _pam_log_debug(ctx, LOG_DEBUG,
- "unable to obtain a password");
- return retval;
- }
- /* 'token' is the entered password */
-
- /* we store this password as an item */
-
- retval = pam_set_item(ctx->pamh, authtok_flag, token);
- _pam_delete(token); /* clean it up */
- if (retval != PAM_SUCCESS ||
- (retval = _pam_get_item(ctx->pamh, authtok_flag, &item)) != PAM_SUCCESS) {
-
- _pam_log(ctx, LOG_CRIT, "error manipulating password");
- return retval;
-
- }
-
- *pass = item;
- item = NULL; /* break link to password */
-
- return PAM_SUCCESS;
-}
-
-static const char *get_conf_item_string(struct pwb_context *ctx,
- const char *item,
- int config_flag)
-{
- int i = 0;
- const char *parm_opt = NULL;
-
- if (!(ctx->ctrl & config_flag)) {
- goto out;
- }
-
- /* let the pam opt take precedence over the pam_winbind.conf option */
- for (i=0; i<ctx->argc; i++) {
-
- if ((strncmp(ctx->argv[i], item, strlen(item)) == 0)) {
- char *p;
-
- if ((p = strchr(ctx->argv[i], '=')) == NULL) {
- _pam_log(ctx, LOG_INFO,
- "no \"=\" delimiter for \"%s\" found\n",
- item);
- goto out;
- }
- _pam_log_debug(ctx, LOG_INFO,
- "PAM config: %s '%s'\n", item, p+1);
- return p + 1;
- }
- }
-
- if (ctx->dict) {
- char *key = NULL;
-
- key = talloc_asprintf(ctx, "global:%s", item);
- if (!key) {
- goto out;
- }
-
- parm_opt = iniparser_getstr(ctx->dict, key);
- TALLOC_FREE(key);
-
- _pam_log_debug(ctx, LOG_INFO, "CONFIG file: %s '%s'\n",
- item, parm_opt);
- }
-out:
- return parm_opt;
-}
-
-static int get_config_item_int(struct pwb_context *ctx,
- const char *item,
- int config_flag)
-{
- int i, parm_opt = -1;
-
- if (!(ctx->ctrl & config_flag)) {
- goto out;
- }
-
- /* let the pam opt take precedence over the pam_winbind.conf option */
- for (i = 0; i < ctx->argc; i++) {
-
- if ((strncmp(ctx->argv[i], item, strlen(item)) == 0)) {
- char *p;
-
- if ((p = strchr(ctx->argv[i], '=')) == NULL) {
- _pam_log(ctx, LOG_INFO,
- "no \"=\" delimiter for \"%s\" found\n",
- item);
- goto out;
- }
- parm_opt = atoi(p + 1);
- _pam_log_debug(ctx, LOG_INFO,
- "PAM config: %s '%d'\n",
- item, parm_opt);
- return parm_opt;
- }
- }
-
- if (ctx->dict) {
- char *key = NULL;
-
- key = talloc_asprintf(ctx, "global:%s", item);
- if (!key) {
- goto out;
- }
-
- parm_opt = iniparser_getint(ctx->dict, key, -1);
- TALLOC_FREE(key);
-
- _pam_log_debug(ctx, LOG_INFO,
- "CONFIG file: %s '%d'\n",
- item, parm_opt);
- }
-out:
- return parm_opt;
-}
-
-static const char *get_krb5_cc_type_from_config(struct pwb_context *ctx)
-{
- return get_conf_item_string(ctx, "krb5_ccache_type",
- WINBIND_KRB5_CCACHE_TYPE);
-}
-
-static const char *get_member_from_config(struct pwb_context *ctx)
-{
- const char *ret = NULL;
- ret = get_conf_item_string(ctx, "require_membership_of",
- WINBIND_REQUIRED_MEMBERSHIP);
- if (ret) {
- return ret;
- }
- return get_conf_item_string(ctx, "require-membership-of",
- WINBIND_REQUIRED_MEMBERSHIP);
-}
-
-static int get_warn_pwd_expire_from_config(struct pwb_context *ctx)
-{
- int ret;
- ret = get_config_item_int(ctx, "warn_pwd_expire",
- WINBIND_WARN_PWD_EXPIRE);
- /* no or broken setting */
- if (ret <= 0) {
- return DEFAULT_DAYS_TO_WARN_BEFORE_PWD_EXPIRES;
- }
- return ret;
-}
-
-/**
- * Retrieve the winbind separator.
- *
- * @param ctx PAM winbind context.
- *
- * @return string separator character. NULL on failure.
- */
-
-static char winbind_get_separator(struct pwb_context *ctx)
-{
- wbcErr wbc_status;
- static struct wbcInterfaceDetails *details = NULL;
-
- wbc_status = wbcInterfaceDetails(&details);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- _pam_log(ctx, LOG_ERR,
- "Could not retrieve winbind interface details: %s",
- wbcErrorString(wbc_status));
- return '\0';
- }
-
- if (!details) {
- return '\0';
- }
-
- return details->winbind_separator;
-}
-
-
-/**
- * Convert a upn to a name.
- *
- * @param ctx PAM winbind context.
- * @param upn USer UPN to be trabslated.
- *
- * @return converted name. NULL pointer on failure. Caller needs to free.
- */
-
-static char* winbind_upn_to_username(struct pwb_context *ctx,
- const char *upn)
-{
- char sep;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcDomainSid sid;
- enum wbcSidType type;
- char *domain;
- char *name;
-
- /* This cannot work when the winbind separator = @ */
-
- sep = winbind_get_separator(ctx);
- if (!sep || sep == '@') {
- return NULL;
- }
-
- /* Convert the UPN to a SID */
-
- wbc_status = wbcLookupName("", upn, &sid, &type);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return NULL;
- }
-
- /* Convert the the SID back to the sAMAccountName */
-
- wbc_status = wbcLookupSid(&sid, &domain, &name, &type);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return NULL;
- }
-
- return talloc_asprintf(ctx, "%s\\%s", domain, name);
-}
-
-static int _pam_delete_cred(pam_handle_t *pamh, int flags,
- int argc, const char **argv)
-{
- int retval = PAM_SUCCESS;
- struct pwb_context *ctx = NULL;
- struct wbcLogoffUserParams logoff;
- struct wbcAuthErrorInfo *error = NULL;
- const char *user;
- wbcErr wbc_status = WBC_ERR_SUCCESS;
-
- retval = _pam_winbind_init_context(pamh, flags, argc, argv, &ctx);
- if (retval) {
- goto out;
- }
-
- _PAM_LOG_FUNCTION_ENTER("_pam_delete_cred", ctx);
-
- if (ctx->ctrl & WINBIND_KRB5_AUTH) {
-
- /* destroy the ccache here */
-
- uint32_t wbc_flags = 0;
- const char *ccname = NULL;
- struct passwd *pwd = NULL;
-
- retval = pam_get_user(pamh, &user, _("Username: "));
- if (retval) {
- _pam_log(ctx, LOG_ERR,
- "could not identify user");
- goto out;
- }
-
- if (user == NULL) {
- _pam_log(ctx, LOG_ERR,
- "username was NULL!");
- retval = PAM_USER_UNKNOWN;
- goto out;
- }
-
- _pam_log_debug(ctx, LOG_DEBUG,
- "username [%s] obtained", user);
-
- ccname = pam_getenv(pamh, "KRB5CCNAME");
- if (ccname == NULL) {
- _pam_log_debug(ctx, LOG_DEBUG,
- "user has no KRB5CCNAME environment");
- }
-
- pwd = getpwnam(user);
- if (pwd == NULL) {
- retval = PAM_USER_UNKNOWN;
- goto out;
- }
-
- wbc_flags = WBFLAG_PAM_KRB5 |
- WBFLAG_PAM_CONTACT_TRUSTDOM;
-
- ZERO_STRUCT(logoff);
-
- logoff.username = user;
-
- if (ccname) {
- wbc_status = wbcAddNamedBlob(&logoff.num_blobs,
- &logoff.blobs,
- "ccfilename",
- 0,
- (uint8_t *)ccname,
- strlen(ccname)+1);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- goto out;
- }
- }
-
- wbc_status = wbcAddNamedBlob(&logoff.num_blobs,
- &logoff.blobs,
- "flags",
- 0,
- (uint8_t *)&wbc_flags,
- sizeof(wbc_flags));
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- goto out;
- }
-
- wbc_status = wbcAddNamedBlob(&logoff.num_blobs,
- &logoff.blobs,
- "user_uid",
- 0,
- (uint8_t *)&pwd->pw_uid,
- sizeof(pwd->pw_uid));
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- goto out;
- }
-
- wbc_status = wbcLogoffUserEx(&logoff, &error);
- retval = wbc_auth_error_to_pam_error(ctx, error, wbc_status,
- user, "wbcLogoffUser");
- wbcFreeMemory(error);
- wbcFreeMemory(logoff.blobs);
-
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- _pam_log(ctx, LOG_INFO,
- "failed to logoff user %s: %s\n",
- user, wbcErrorString(wbc_status));
- }
- }
-
-out:
- if (logoff.blobs) {
- wbcFreeMemory(logoff.blobs);
- }
-
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- retval = wbc_auth_error_to_pam_error(ctx, error, wbc_status,
- user, "wbcLogoffUser");
- }
-
- /*
- * Delete the krb5 ccname variable from the PAM environment
- * if it was set by winbind.
- */
- if (ctx->ctrl & WINBIND_KRB5_AUTH) {
- pam_putenv(pamh, "KRB5CCNAME");
- }
-
- _PAM_LOG_FUNCTION_LEAVE("_pam_delete_cred", ctx, retval);
-
- TALLOC_FREE(ctx);
-
- return retval;
-}
-
-PAM_EXTERN
-int pam_sm_authenticate(pam_handle_t *pamh, int flags,
- int argc, const char **argv)
-{
- const char *username;
- const char *password;
- const char *member = NULL;
- const char *cctype = NULL;
- int warn_pwd_expire;
- int retval = PAM_AUTH_ERR;
- char *username_ret = NULL;
- char *new_authtok_required = NULL;
- char *real_username = NULL;
- struct pwb_context *ctx = NULL;
-
- retval = _pam_winbind_init_context(pamh, flags, argc, argv, &ctx);
- if (retval) {
- goto out;
- }
-
- _PAM_LOG_FUNCTION_ENTER("pam_sm_authenticate", ctx);
-
- /* Get the username */
- retval = pam_get_user(pamh, &username, NULL);
- if ((retval != PAM_SUCCESS) || (!username)) {
- _pam_log_debug(ctx, LOG_DEBUG,
- "can not get the username");
- retval = PAM_SERVICE_ERR;
- goto out;
- }
-
-
-#if defined(AIX)
- /* Decode the user name since AIX does not support logn user
- names by default. The name is encoded as _#uid. */
-
- if (username[0] == '_') {
- uid_t id = atoi(&username[1]);
- struct passwd *pw = NULL;
-
- if ((id!=0) && ((pw = getpwuid(id)) != NULL)) {
- real_username = strdup(pw->pw_name);
- }
- }
-#endif
-
- if (!real_username) {
- /* Just making a copy of the username we got from PAM */
- if ((real_username = strdup(username)) == NULL) {
- _pam_log_debug(ctx, LOG_DEBUG,
- "memory allocation failure when copying "
- "username");
- retval = PAM_SERVICE_ERR;
- goto out;
- }
- }
-
- /* Maybe this was a UPN */
-
- if (strchr(real_username, '@') != NULL) {
- char *samaccountname = NULL;
-
- samaccountname = winbind_upn_to_username(ctx,
- real_username);
- if (samaccountname) {
- free(real_username);
- real_username = strdup(samaccountname);
- }
- }
-
- retval = _winbind_read_password(ctx, ctx->ctrl, NULL,
- _("Password: "), NULL,
- &password);
-
- if (retval != PAM_SUCCESS) {
- _pam_log(ctx, LOG_ERR,
- "Could not retrieve user's password");
- retval = PAM_AUTHTOK_ERR;
- goto out;
- }
-
- /* Let's not give too much away in the log file */
-
-#ifdef DEBUG_PASSWORD
- _pam_log_debug(ctx, LOG_INFO,
- "Verify user '%s' with password '%s'",
- real_username, password);
-#else
- _pam_log_debug(ctx, LOG_INFO,
- "Verify user '%s'", real_username);
-#endif
-
- member = get_member_from_config(ctx);
- cctype = get_krb5_cc_type_from_config(ctx);
- warn_pwd_expire = get_warn_pwd_expire_from_config(ctx);
-
- /* Now use the username to look up password */
- retval = winbind_auth_request(ctx, real_username, password,
- member, cctype, warn_pwd_expire,
- NULL, NULL, NULL,
- NULL, &username_ret);
-
- if (retval == PAM_NEW_AUTHTOK_REQD ||
- retval == PAM_AUTHTOK_EXPIRED) {
-
- char *new_authtok_required_during_auth = NULL;
-
- new_authtok_required = talloc_asprintf(NULL, "%d", retval);
- if (!new_authtok_required) {
- retval = PAM_BUF_ERR;
- goto out;
- }
-
- pam_set_data(pamh, PAM_WINBIND_NEW_AUTHTOK_REQD,
- new_authtok_required,
- _pam_winbind_cleanup_func);
-
- retval = PAM_SUCCESS;
-
- new_authtok_required_during_auth = talloc_asprintf(NULL, "%d", true);
- if (!new_authtok_required_during_auth) {
- retval = PAM_BUF_ERR;
- goto out;
- }
-
- pam_set_data(pamh, PAM_WINBIND_NEW_AUTHTOK_REQD_DURING_AUTH,
- new_authtok_required_during_auth,
- _pam_winbind_cleanup_func);
-
- goto out;
- }
-
-out:
- if (username_ret) {
- pam_set_item (pamh, PAM_USER, username_ret);
- _pam_log_debug(ctx, LOG_INFO,
- "Returned user was '%s'", username_ret);
- free(username_ret);
- }
-
- if (real_username) {
- free(real_username);
- }
-
- if (!new_authtok_required) {
- pam_set_data(pamh, PAM_WINBIND_NEW_AUTHTOK_REQD, NULL, NULL);
- }
-
- if (retval != PAM_SUCCESS) {
- _pam_free_data_info3(pamh);
- }
-
- _PAM_LOG_FUNCTION_LEAVE("pam_sm_authenticate", ctx, retval);
-
- TALLOC_FREE(ctx);
-
- return retval;
-}
-
-PAM_EXTERN
-int pam_sm_setcred(pam_handle_t *pamh, int flags,
- int argc, const char **argv)
-{
- int ret = PAM_SYSTEM_ERR;
- struct pwb_context *ctx = NULL;
-
- ret = _pam_winbind_init_context(pamh, flags, argc, argv, &ctx);
- if (ret) {
- goto out;
- }
-
- _PAM_LOG_FUNCTION_ENTER("pam_sm_setcred", ctx);
-
- switch (flags & ~PAM_SILENT) {
-
- case PAM_DELETE_CRED:
- ret = _pam_delete_cred(pamh, flags, argc, argv);
- break;
- case PAM_REFRESH_CRED:
- _pam_log_debug(ctx, LOG_WARNING,
- "PAM_REFRESH_CRED not implemented");
- ret = PAM_SUCCESS;
- break;
- case PAM_REINITIALIZE_CRED:
- _pam_log_debug(ctx, LOG_WARNING,
- "PAM_REINITIALIZE_CRED not implemented");
- ret = PAM_SUCCESS;
- break;
- case PAM_ESTABLISH_CRED:
- _pam_log_debug(ctx, LOG_WARNING,
- "PAM_ESTABLISH_CRED not implemented");
- ret = PAM_SUCCESS;
- break;
- default:
- ret = PAM_SYSTEM_ERR;
- break;
- }
-
- out:
-
- _PAM_LOG_FUNCTION_LEAVE("pam_sm_setcred", ctx, ret);
-
- TALLOC_FREE(ctx);
-
- return ret;
-}
-
-/*
- * Account management. We want to verify that the account exists
- * before returning PAM_SUCCESS
- */
-PAM_EXTERN
-int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
- int argc, const char **argv)
-{
- const char *username;
- int ret = PAM_USER_UNKNOWN;
- void *tmp = NULL;
- struct pwb_context *ctx = NULL;
-
- ret = _pam_winbind_init_context(pamh, flags, argc, argv, &ctx);
- if (ret) {
- goto out;
- }
-
- _PAM_LOG_FUNCTION_ENTER("pam_sm_acct_mgmt", ctx);
-
-
- /* Get the username */
- ret = pam_get_user(pamh, &username, NULL);
- if ((ret != PAM_SUCCESS) || (!username)) {
- _pam_log_debug(ctx, LOG_DEBUG,
- "can not get the username");
- ret = PAM_SERVICE_ERR;
- goto out;
- }
-
- /* Verify the username */
- ret = valid_user(ctx, username);
- switch (ret) {
- case -1:
- /* some sort of system error. The log was already printed */
- ret = PAM_SERVICE_ERR;
- goto out;
- case 1:
- /* the user does not exist */
- _pam_log_debug(ctx, LOG_NOTICE, "user '%s' not found",
- username);
- if (ctx->ctrl & WINBIND_UNKNOWN_OK_ARG) {
- ret = PAM_IGNORE;
- goto out;
- }
- ret = PAM_USER_UNKNOWN;
- goto out;
- case 0:
- pam_get_data(pamh, PAM_WINBIND_NEW_AUTHTOK_REQD,
- (const void **)&tmp);
- if (tmp != NULL) {
- ret = atoi((const char *)tmp);
- switch (ret) {
- case PAM_AUTHTOK_EXPIRED:
- /* fall through, since new token is required in this case */
- case PAM_NEW_AUTHTOK_REQD:
- _pam_log(ctx, LOG_WARNING,
- "pam_sm_acct_mgmt success but %s is set",
- PAM_WINBIND_NEW_AUTHTOK_REQD);
- _pam_log(ctx, LOG_NOTICE,
- "user '%s' needs new password",
- username);
- /* PAM_AUTHTOKEN_REQD does not exist, but is documented in the manpage */
- ret = PAM_NEW_AUTHTOK_REQD;
- goto out;
- default:
- _pam_log(ctx, LOG_WARNING,
- "pam_sm_acct_mgmt success");
- _pam_log(ctx, LOG_NOTICE,
- "user '%s' granted access", username);
- ret = PAM_SUCCESS;
- goto out;
- }
- }
-
- /* Otherwise, the authentication looked good */
- _pam_log(ctx, LOG_NOTICE,
- "user '%s' granted access", username);
- ret = PAM_SUCCESS;
- goto out;
- default:
- /* we don't know anything about this return value */
- _pam_log(ctx, LOG_ERR,
- "internal module error (ret = %d, user = '%s')",
- ret, username);
- ret = PAM_SERVICE_ERR;
- goto out;
- }
-
- /* should not be reached */
- ret = PAM_IGNORE;
-
- out:
-
- _PAM_LOG_FUNCTION_LEAVE("pam_sm_acct_mgmt", ctx, ret);
-
- TALLOC_FREE(ctx);
-
- return ret;
-}
-
-PAM_EXTERN
-int pam_sm_open_session(pam_handle_t *pamh, int flags,
- int argc, const char **argv)
-{
- int ret = PAM_SUCCESS;
- struct pwb_context *ctx = NULL;
-
- ret = _pam_winbind_init_context(pamh, flags, argc, argv, &ctx);
- if (ret) {
- goto out;
- }
-
- _PAM_LOG_FUNCTION_ENTER("pam_sm_open_session", ctx);
-
- if (ctx->ctrl & WINBIND_MKHOMEDIR) {
- /* check and create homedir */
- ret = _pam_mkhomedir(ctx);
- }
- out:
- _PAM_LOG_FUNCTION_LEAVE("pam_sm_open_session", ctx, ret);
-
- TALLOC_FREE(ctx);
-
- return ret;
-}
-
-PAM_EXTERN
-int pam_sm_close_session(pam_handle_t *pamh, int flags,
- int argc, const char **argv)
-{
- int ret = PAM_SUCCESS;
- struct pwb_context *ctx = NULL;
-
- ret = _pam_winbind_init_context(pamh, flags, argc, argv, &ctx);
- if (ret) {
- goto out;
- }
-
- _PAM_LOG_FUNCTION_ENTER("pam_sm_close_session", ctx);
-
-out:
- _PAM_LOG_FUNCTION_LEAVE("pam_sm_close_session", ctx, ret);
-
- TALLOC_FREE(ctx);
-
- return ret;
-}
-
-/**
- * evaluate whether we need to re-authenticate with kerberos after a
- * password change
- *
- * @param ctx PAM winbind context.
- * @param user The username
- *
- * @return boolean Returns true if required, false if not.
- */
-
-static bool _pam_require_krb5_auth_after_chauthtok(struct pwb_context *ctx,
- const char *user)
-{
-
- /* Make sure that we only do this if a) the chauthtok got initiated
- * during a logon attempt (authenticate->acct_mgmt->chauthtok) b) any
- * later password change via the "passwd" command if done by the user
- * itself
- * NB. If we login from gdm or xdm and the password expires,
- * we change the password, but there is no memory cache.
- * Thus, even for passthrough login, we should do the
- * authentication again to update memory cache.
- * --- BoYang
- * */
-
- char *new_authtok_reqd_during_auth = NULL;
- struct passwd *pwd = NULL;
-
- _pam_get_data(ctx->pamh, PAM_WINBIND_NEW_AUTHTOK_REQD_DURING_AUTH,
- &new_authtok_reqd_during_auth);
- pam_set_data(ctx->pamh, PAM_WINBIND_NEW_AUTHTOK_REQD_DURING_AUTH,
- NULL, NULL);
-
- if (new_authtok_reqd_during_auth) {
- return true;
- }
-
- pwd = getpwnam(user);
- if (!pwd) {
- return false;
- }
-
- if (getuid() == pwd->pw_uid) {
- return true;
- }
-
- return false;
-}
-
-
-PAM_EXTERN
-int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
- int argc, const char **argv)
-{
- unsigned int lctrl;
- int ret;
- bool cached_login = false;
-
- /* <DO NOT free() THESE> */
- const char *user;
- char *pass_old, *pass_new;
- /* </DO NOT free() THESE> */
-
- char *Announce;
-
- int retry = 0;
- char *username_ret = NULL;
- struct wbcAuthErrorInfo *error = NULL;
- struct pwb_context *ctx = NULL;
-
- ret = _pam_winbind_init_context(pamh, flags, argc, argv, &ctx);
- if (ret) {
- goto out;
- }
-
- _PAM_LOG_FUNCTION_ENTER("pam_sm_chauthtok", ctx);
-
- cached_login = (ctx->ctrl & WINBIND_CACHED_LOGIN);
-
- /* clearing offline bit for auth */
- ctx->ctrl &= ~WINBIND_CACHED_LOGIN;
-
- /*
- * First get the name of a user
- */
- ret = pam_get_user(pamh, &user, _("Username: "));
- if (ret) {
- _pam_log(ctx, LOG_ERR,
- "password - could not identify user");
- goto out;
- }
-
- if (user == NULL) {
- _pam_log(ctx, LOG_ERR, "username was NULL!");
- ret = PAM_USER_UNKNOWN;
- goto out;
- }
-
- _pam_log_debug(ctx, LOG_DEBUG, "username [%s] obtained", user);
-
- /* check if this is really a user in winbindd, not only in NSS */
- ret = valid_user(ctx, user);
- switch (ret) {
- case 1:
- ret = PAM_USER_UNKNOWN;
- goto out;
- case -1:
- ret = PAM_SYSTEM_ERR;
- goto out;
- default:
- break;
- }
-
- /*
- * obtain and verify the current password (OLDAUTHTOK) for
- * the user.
- */
-
- if (flags & PAM_PRELIM_CHECK) {
- time_t pwdlastset_prelim = 0;
-
- /* instruct user what is happening */
-
-#define greeting _("Changing password for")
- Announce = talloc_asprintf(ctx, "%s %s", greeting, user);
- if (!Announce) {
- _pam_log(ctx, LOG_CRIT,
- "password - out of memory");
- ret = PAM_BUF_ERR;
- goto out;
- }
-#undef greeting
-
- lctrl = ctx->ctrl | WINBIND__OLD_PASSWORD;
- ret = _winbind_read_password(ctx, lctrl,
- Announce,
- _("(current) NT password: "),
- NULL,
- (const char **) &pass_old);
- TALLOC_FREE(Announce);
- if (ret != PAM_SUCCESS) {
- _pam_log(ctx, LOG_NOTICE,
- "password - (old) token not obtained");
- goto out;
- }
-
- /* verify that this is the password for this user */
-
- ret = winbind_auth_request(ctx, user, pass_old,
- NULL, NULL, 0,
- &error, NULL, NULL,
- &pwdlastset_prelim, NULL);
-
- if (ret != PAM_ACCT_EXPIRED &&
- ret != PAM_AUTHTOK_EXPIRED &&
- ret != PAM_NEW_AUTHTOK_REQD &&
- ret != PAM_SUCCESS) {
- pass_old = NULL;
- goto out;
- }
-
- pam_set_data(pamh, PAM_WINBIND_PWD_LAST_SET,
- (void *)pwdlastset_prelim, NULL);
-
- ret = pam_set_item(pamh, PAM_OLDAUTHTOK,
- (const void *) pass_old);
- pass_old = NULL;
- if (ret != PAM_SUCCESS) {
- _pam_log(ctx, LOG_CRIT,
- "failed to set PAM_OLDAUTHTOK");
- }
- } else if (flags & PAM_UPDATE_AUTHTOK) {
-
- time_t pwdlastset_update = 0;
-
- /*
- * obtain the proposed password
- */
-
- /*
- * get the old token back.
- */
-
- ret = _pam_get_item(pamh, PAM_OLDAUTHTOK, &pass_old);
-
- if (ret != PAM_SUCCESS) {
- _pam_log(ctx, LOG_NOTICE,
- "user not authenticated");
- goto out;
- }
-
- lctrl = ctx->ctrl & ~WINBIND_TRY_FIRST_PASS_ARG;
-
- if (on(WINBIND_USE_AUTHTOK_ARG, lctrl)) {
- lctrl |= WINBIND_USE_FIRST_PASS_ARG;
- }
- retry = 0;
- ret = PAM_AUTHTOK_ERR;
- while ((ret != PAM_SUCCESS) && (retry++ < MAX_PASSWD_TRIES)) {
- /*
- * use_authtok is to force the use of a previously entered
- * password -- needed for pluggable password strength checking
- */
-
- ret = _winbind_read_password(ctx, lctrl,
- NULL,
- _("Enter new NT password: "),
- _("Retype new NT password: "),
- (const char **)&pass_new);
-
- if (ret != PAM_SUCCESS) {
- _pam_log_debug(ctx, LOG_ALERT,
- "password - "
- "new password not obtained");
- pass_old = NULL;/* tidy up */
- goto out;
- }
-
- /*
- * At this point we know who the user is and what they
- * propose as their new password. Verify that the new
- * password is acceptable.
- */
-
- if (pass_new[0] == '\0') {/* "\0" password = NULL */
- pass_new = NULL;
- }
- }
-
- /*
- * By reaching here we have approved the passwords and must now
- * rebuild the password database file.
- */
- _pam_get_data(pamh, PAM_WINBIND_PWD_LAST_SET,
- &pwdlastset_update);
-
- /*
- * if cached creds were enabled, make sure to set the
- * WINBIND_CACHED_LOGIN bit here in order to have winbindd
- * update the cached creds storage - gd
- */
- if (cached_login) {
- ctx->ctrl |= WINBIND_CACHED_LOGIN;
- }
-
- ret = winbind_chauthtok_request(ctx, user, pass_old,
- pass_new, pwdlastset_update);
- if (ret) {
- _pam_overwrite(pass_new);
- _pam_overwrite(pass_old);
- pass_old = pass_new = NULL;
- goto out;
- }
-
- if (_pam_require_krb5_auth_after_chauthtok(ctx, user)) {
-
- const char *member = NULL;
- const char *cctype = NULL;
- int warn_pwd_expire;
- struct wbcLogonUserInfo *info = NULL;
- struct wbcUserPasswordPolicyInfo *policy = NULL;
-
- member = get_member_from_config(ctx);
- cctype = get_krb5_cc_type_from_config(ctx);
- warn_pwd_expire = get_warn_pwd_expire_from_config(ctx);
-
- /* Keep WINBIND_CACHED_LOGIN bit for
- * authentication after changing the password.
- * This will update the cached credentials in case
- * that winbindd_dual_pam_chauthtok() fails
- * to update them.
- * --- BoYang
- * */
-
- ret = winbind_auth_request(ctx, user, pass_new,
- member, cctype, 0,
- &error, &info, &policy,
- NULL, &username_ret);
- _pam_overwrite(pass_new);
- _pam_overwrite(pass_old);
- pass_old = pass_new = NULL;
-
- if (ret == PAM_SUCCESS) {
-
- struct wbcAuthUserInfo *user_info = NULL;
-
- if (info && info->info) {
- user_info = info->info;
- }
-
- /* warn a user if the password is about to
- * expire soon */
- _pam_warn_password_expiry(ctx, user_info, policy,
- warn_pwd_expire,
- NULL);
-
- /* set some info3 info for other modules in the
- * stack */
- _pam_set_data_info3(ctx, user_info);
-
- /* put krb5ccname into env */
- _pam_setup_krb5_env(ctx, info);
-
- if (username_ret) {
- pam_set_item(pamh, PAM_USER,
- username_ret);
- _pam_log_debug(ctx, LOG_INFO,
- "Returned user was '%s'",
- username_ret);
- free(username_ret);
- }
-
- wbcFreeMemory(info);
- wbcFreeMemory(policy);
- }
-
- goto out;
- }
- } else {
- ret = PAM_SERVICE_ERR;
- }
-
-out:
- {
- /* Deal with offline errors. */
- int i;
- const char *codes[] = {
- "NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND",
- "NT_STATUS_NO_LOGON_SERVERS",
- "NT_STATUS_ACCESS_DENIED"
- };
-
- for (i=0; i<ARRAY_SIZE(codes); i++) {
- int _ret;
- if (_pam_check_remark_auth_err(ctx, error, codes[i], &_ret)) {
- break;
- }
- }
- }
-
- wbcFreeMemory(error);
-
- _PAM_LOG_FUNCTION_LEAVE("pam_sm_chauthtok", ctx, ret);
-
- TALLOC_FREE(ctx);
-
- return ret;
-}
-
-#ifdef PAM_STATIC
-
-/* static module data */
-
-struct pam_module _pam_winbind_modstruct = {
- MODULE_NAME,
- pam_sm_authenticate,
- pam_sm_setcred,
- pam_sm_acct_mgmt,
- pam_sm_open_session,
- pam_sm_close_session,
- pam_sm_chauthtok
-};
-
-#endif
-
-/*
- * Copyright (c) Andrew Tridgell <tridge@samba.org> 2000
- * Copyright (c) Tim Potter <tpot@samba.org> 2000
- * Copyright (c) Andrew Bartlettt <abartlet@samba.org> 2002
- * Copyright (c) Guenther Deschner <gd@samba.org> 2005-2008
- * Copyright (c) Jan Rêkorajski 1999.
- * Copyright (c) Andrew G. Morgan 1996-8.
- * Copyright (c) Alex O. Yuriev, 1996.
- * Copyright (c) Cristian Gafton 1996.
- * Copyright (C) Elliot Lee <sopwith@redhat.com> 1996, Red Hat Software.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * ALTERNATIVELY, this product may be distributed under the terms of
- * the GNU Public License, in which case the provisions of the GPL are
- * required INSTEAD OF the above restrictions. (This clause is
- * necessary due to a potential bad interaction between the GPL and
- * the restrictions contained in a BSD-style copyright.)
- *
- * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
diff --git a/source3/nsswitch/pam_winbind.h b/source3/nsswitch/pam_winbind.h
deleted file mode 100644
index 0656f5972e..0000000000
--- a/source3/nsswitch/pam_winbind.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/* pam_winbind header file
- (Solaris needs some macros from Linux for common PAM code)
-
- Shirish Kalele 2000
-*/
-
-#include "../lib/replace/replace.h"
-#include "system/syslog.h"
-#include "system/time.h"
-#include <talloc.h>
-#include "libwbclient/wbclient.h"
-#include "localedir.h"
-
-#define MODULE_NAME "pam_winbind"
-#define PAM_SM_AUTH
-#define PAM_SM_ACCOUNT
-#define PAM_SM_PASSWORD
-#define PAM_SM_SESSION
-
-#ifndef PAM_WINBIND_CONFIG_FILE
-#define PAM_WINBIND_CONFIG_FILE "/etc/security/pam_winbind.conf"
-#endif
-
-#include <iniparser.h>
-
-#ifdef HAVE_LIBINTL_H
-#include <libintl.h>
-#endif
-
-#ifndef LINUX
-
-/* Solaris always uses dynamic pam modules */
-#define PAM_EXTERN extern
-#if defined(HAVE_SECURITY_PAM_APPL_H)
-#include <security/pam_appl.h>
-#elif defined(HAVE_PAM_PAM_APPL_H)
-#include <pam/pam_appl.h>
-#endif
-
-#ifndef PAM_AUTHTOK_RECOVER_ERR
-#define PAM_AUTHTOK_RECOVER_ERR PAM_AUTHTOK_RECOVERY_ERR
-#endif
-
-#endif /* defined(SUNOS5) || defined(SUNOS4) || defined(HPUX) || defined(FREEBSD) || defined(AIX) */
-
-#if defined(HAVE_SECURITY_PAM_MODULES_H)
-#include <security/pam_modules.h>
-#elif defined(HAVE_PAM_PAM_MODULES_H)
-#include <pam/pam_modules.h>
-#endif
-
-#if defined(HAVE_SECURITY__PAM_MACROS_H)
-#include <security/_pam_macros.h>
-#elif defined(HAVE_PAM__PAM_MACROS_H)
-#include <pam/_pam_macros.h>
-#else
-/* Define required macros from (Linux PAM 0.68) security/_pam_macros.h */
-#define _pam_drop_reply(/* struct pam_response * */ reply, /* int */ replies) \
-do { \
- int reply_i; \
- \
- for (reply_i=0; reply_i<replies; ++reply_i) { \
- if (reply[reply_i].resp) { \
- _pam_overwrite(reply[reply_i].resp); \
- free(reply[reply_i].resp); \
- } \
- } \
- if (reply) \
- free(reply); \
-} while (0)
-
-#define _pam_overwrite(x) \
-do { \
- register char *__xx__; \
- if ((__xx__=(x))) \
- while (*__xx__) \
- *__xx__++ = '\0'; \
-} while (0)
-
-/*
- * Don't just free it, forget it too.
- */
-
-#define _pam_drop(X) SAFE_FREE(X)
-
-#define x_strdup(s) ( (s) ? strdup(s):NULL )
-#endif /* HAVE_SECURITY__PAM_MACROS_H */
-
-#ifdef HAVE_SECURITY_PAM_EXT_H
-#include <security/pam_ext.h>
-#endif
-
-#define WINBIND_DEBUG_ARG 0x00000001
-#define WINBIND_USE_AUTHTOK_ARG 0x00000002
-#define WINBIND_UNKNOWN_OK_ARG 0x00000004
-#define WINBIND_TRY_FIRST_PASS_ARG 0x00000008
-#define WINBIND_USE_FIRST_PASS_ARG 0x00000010
-#define WINBIND__OLD_PASSWORD 0x00000020
-#define WINBIND_REQUIRED_MEMBERSHIP 0x00000040
-#define WINBIND_KRB5_AUTH 0x00000080
-#define WINBIND_KRB5_CCACHE_TYPE 0x00000100
-#define WINBIND_CACHED_LOGIN 0x00000200
-#define WINBIND_CONFIG_FILE 0x00000400
-#define WINBIND_SILENT 0x00000800
-#define WINBIND_DEBUG_STATE 0x00001000
-#define WINBIND_WARN_PWD_EXPIRE 0x00002000
-#define WINBIND_MKHOMEDIR 0x00004000
-
-#if defined(HAVE_GETTEXT) && !defined(__LCLINT__)
-#define _(string) dgettext(MODULE_NAME, string)
-#else
-#define _(string) string
-#endif
-
-#define N_(string) string
-
-/*
- * here is the string to inform the user that the new passwords they
- * typed were not the same.
- */
-
-#define MISTYPED_PASS _("Sorry, passwords do not match")
-
-#define on(x, y) (x & y)
-#define off(x, y) (!(x & y))
-
-#define PAM_WINBIND_NEW_AUTHTOK_REQD "PAM_WINBIND_NEW_AUTHTOK_REQD"
-#define PAM_WINBIND_NEW_AUTHTOK_REQD_DURING_AUTH "PAM_WINBIND_NEW_AUTHTOK_REQD_DURING_AUTH"
-#define PAM_WINBIND_HOMEDIR "PAM_WINBIND_HOMEDIR"
-#define PAM_WINBIND_LOGONSCRIPT "PAM_WINBIND_LOGONSCRIPT"
-#define PAM_WINBIND_LOGONSERVER "PAM_WINBIND_LOGONSERVER"
-#define PAM_WINBIND_PROFILEPATH "PAM_WINBIND_PROFILEPATH"
-#define PAM_WINBIND_PWD_LAST_SET "PAM_WINBIND_PWD_LAST_SET"
-
-#define SECONDS_PER_DAY 86400
-
-#define DEFAULT_DAYS_TO_WARN_BEFORE_PWD_EXPIRES 14
-
-#include "winbind_client.h"
-
-#define PAM_WB_REMARK_DIRECT(c,x)\
-{\
- const char *error_string = NULL; \
- error_string = _get_ntstatus_error_string(x);\
- if (error_string != NULL) {\
- _make_remark(c, PAM_ERROR_MSG, error_string);\
- } else {\
- _make_remark(c, PAM_ERROR_MSG, x);\
- };\
-};
-
-#define LOGON_KRB5_FAIL_CLOCK_SKEW 0x02000000
-
-#define PAM_WB_CACHED_LOGON(x) (x & WBC_AUTH_USER_INFO_CACHED_ACCOUNT)
-#define PAM_WB_KRB5_CLOCK_SKEW(x) (x & LOGON_KRB5_FAIL_CLOCK_SKEW)
-#define PAM_WB_GRACE_LOGON(x) ((WBC_AUTH_USER_INFO_CACHED_ACCOUNT|WBC_AUTH_USER_INFO_GRACE_LOGON) == ( x & (WBC_AUTH_USER_INFO_CACHED_ACCOUNT|WBC_AUTH_USER_INFO_GRACE_LOGON)))
-
-struct pwb_context {
- pam_handle_t *pamh;
- int flags;
- int argc;
- const char **argv;
- dictionary *dict;
- uint32_t ctrl;
-};
-
-#define TALLOC_FREE(ctx) do { if ((ctx) != NULL) {talloc_free(ctx); ctx=NULL;} } while(0)
-#define TALLOC_ZERO_P(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type)
-#define TALLOC_P(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type)
-
diff --git a/source3/nsswitch/wb_common.c b/source3/nsswitch/wb_common.c
deleted file mode 100644
index a1646215bd..0000000000
--- a/source3/nsswitch/wb_common.c
+++ /dev/null
@@ -1,690 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- winbind client common code
-
- Copyright (C) Tim Potter 2000
- Copyright (C) Andrew Tridgell 2000
- Copyright (C) Andrew Bartlett 2002
-
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "winbind_client.h"
-
-/* Global variables. These are effectively the client state information */
-
-int winbindd_fd = -1; /* fd for winbindd socket */
-static int is_privileged = 0;
-
-/* Free a response structure */
-
-void winbindd_free_response(struct winbindd_response *response)
-{
- /* Free any allocated extra_data */
-
- if (response)
- SAFE_FREE(response->extra_data.data);
-}
-
-/* Initialise a request structure */
-
-void winbindd_init_request(struct winbindd_request *request, int request_type)
-{
- request->length = sizeof(struct winbindd_request);
-
- request->cmd = (enum winbindd_cmd)request_type;
- request->pid = getpid();
-
-}
-
-/* Initialise a response structure */
-
-static void init_response(struct winbindd_response *response)
-{
- /* Initialise return value */
-
- response->result = WINBINDD_ERROR;
-}
-
-/* Close established socket */
-
-void winbind_close_sock(void)
-{
- if (winbindd_fd != -1) {
- close(winbindd_fd);
- winbindd_fd = -1;
- }
-}
-
-#define CONNECT_TIMEOUT 30
-
-/* Make sure socket handle isn't stdin, stdout or stderr */
-#define RECURSION_LIMIT 3
-
-static int make_nonstd_fd_internals(int fd, int limit /* Recursion limiter */)
-{
- int new_fd;
- if (fd >= 0 && fd <= 2) {
-#ifdef F_DUPFD
- if ((new_fd = fcntl(fd, F_DUPFD, 3)) == -1) {
- return -1;
- }
- /* Paranoia */
- if (new_fd < 3) {
- close(new_fd);
- return -1;
- }
- close(fd);
- return new_fd;
-#else
- if (limit <= 0)
- return -1;
-
- new_fd = dup(fd);
- if (new_fd == -1)
- return -1;
-
- /* use the program stack to hold our list of FDs to close */
- new_fd = make_nonstd_fd_internals(new_fd, limit - 1);
- close(fd);
- return new_fd;
-#endif
- }
- return fd;
-}
-
-/****************************************************************************
- Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
- else
- if SYSV use O_NDELAY
- if BSD use FNDELAY
- Set close on exec also.
-****************************************************************************/
-
-static int make_safe_fd(int fd)
-{
- int result, flags;
- int new_fd = make_nonstd_fd_internals(fd, RECURSION_LIMIT);
- if (new_fd == -1) {
- close(fd);
- return -1;
- }
-
- /* Socket should be nonblocking. */
-#ifdef O_NONBLOCK
-#define FLAG_TO_SET O_NONBLOCK
-#else
-#ifdef SYSV
-#define FLAG_TO_SET O_NDELAY
-#else /* BSD */
-#define FLAG_TO_SET FNDELAY
-#endif
-#endif
-
- if ((flags = fcntl(new_fd, F_GETFL)) == -1) {
- close(new_fd);
- return -1;
- }
-
- flags |= FLAG_TO_SET;
- if (fcntl(new_fd, F_SETFL, flags) == -1) {
- close(new_fd);
- return -1;
- }
-
-#undef FLAG_TO_SET
-
- /* Socket should be closed on exec() */
-#ifdef FD_CLOEXEC
- result = flags = fcntl(new_fd, F_GETFD, 0);
- if (flags >= 0) {
- flags |= FD_CLOEXEC;
- result = fcntl( new_fd, F_SETFD, flags );
- }
- if (result < 0) {
- close(new_fd);
- return -1;
- }
-#endif
- return new_fd;
-}
-
-/* Connect to winbindd socket */
-
-static int winbind_named_pipe_sock(const char *dir)
-{
- struct sockaddr_un sunaddr;
- struct stat st;
- char *path = NULL;
- int fd;
- int wait_time;
- int slept;
-
- /* Check permissions on unix socket directory */
-
- if (lstat(dir, &st) == -1) {
- errno = ENOENT;
- return -1;
- }
-
- if (!S_ISDIR(st.st_mode) ||
- (st.st_uid != 0 && st.st_uid != geteuid())) {
- errno = ENOENT;
- return -1;
- }
-
- /* Connect to socket */
-
- if (asprintf(&path, "%s/%s", dir, WINBINDD_SOCKET_NAME) < 0) {
- return -1;
- }
-
- ZERO_STRUCT(sunaddr);
- sunaddr.sun_family = AF_UNIX;
- strncpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path) - 1);
-
- /* If socket file doesn't exist, don't bother trying to connect
- with retry. This is an attempt to make the system usable when
- the winbindd daemon is not running. */
-
- if (lstat(path, &st) == -1) {
- errno = ENOENT;
- SAFE_FREE(path);
- return -1;
- }
-
- SAFE_FREE(path);
- /* Check permissions on unix socket file */
-
- if (!S_ISSOCK(st.st_mode) ||
- (st.st_uid != 0 && st.st_uid != geteuid())) {
- errno = ENOENT;
- return -1;
- }
-
- /* Connect to socket */
-
- if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
- return -1;
- }
-
- /* Set socket non-blocking and close on exec. */
-
- if ((fd = make_safe_fd( fd)) == -1) {
- return fd;
- }
-
- for (wait_time = 0; connect(fd, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1;
- wait_time += slept) {
- struct timeval tv;
- fd_set w_fds;
- int ret;
- int connect_errno = 0;
- socklen_t errnosize;
-
- if (wait_time >= CONNECT_TIMEOUT)
- goto error_out;
-
- switch (errno) {
- case EINPROGRESS:
- FD_ZERO(&w_fds);
- FD_SET(fd, &w_fds);
- tv.tv_sec = CONNECT_TIMEOUT - wait_time;
- tv.tv_usec = 0;
-
- ret = select(fd + 1, NULL, &w_fds, NULL, &tv);
-
- if (ret > 0) {
- errnosize = sizeof(connect_errno);
-
- ret = getsockopt(fd, SOL_SOCKET,
- SO_ERROR, &connect_errno, &errnosize);
-
- if (ret >= 0 && connect_errno == 0) {
- /* Connect succeed */
- goto out;
- }
- }
-
- slept = CONNECT_TIMEOUT;
- break;
- case EAGAIN:
- slept = rand() % 3 + 1;
- sleep(slept);
- break;
- default:
- goto error_out;
- }
-
- }
-
- out:
-
- return fd;
-
- error_out:
-
- close(fd);
- return -1;
-}
-
-static const char *winbindd_socket_dir(void)
-{
-#ifdef SOCKET_WRAPPER
- const char *env_dir;
-
- env_dir = getenv(WINBINDD_SOCKET_DIR_ENVVAR);
- if (env_dir) {
- return env_dir;
- }
-#endif
-
- return WINBINDD_SOCKET_DIR;
-}
-
-/* Connect to winbindd socket */
-
-static int winbind_open_pipe_sock(int recursing, int need_priv)
-{
-#ifdef HAVE_UNIXSOCKET
- static pid_t our_pid;
- struct winbindd_request request;
- struct winbindd_response response;
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- if (our_pid != getpid()) {
- winbind_close_sock();
- our_pid = getpid();
- }
-
- if ((need_priv != 0) && (is_privileged == 0)) {
- winbind_close_sock();
- }
-
- if (winbindd_fd != -1) {
- return winbindd_fd;
- }
-
- if (recursing) {
- return -1;
- }
-
- if ((winbindd_fd = winbind_named_pipe_sock(winbindd_socket_dir())) == -1) {
- return -1;
- }
-
- is_privileged = 0;
-
- /* version-check the socket */
-
- request.wb_flags = WBFLAG_RECURSE;
- if ((winbindd_request_response(WINBINDD_INTERFACE_VERSION, &request, &response) != NSS_STATUS_SUCCESS) || (response.data.interface_version != WINBIND_INTERFACE_VERSION)) {
- winbind_close_sock();
- return -1;
- }
-
- /* try and get priv pipe */
-
- request.wb_flags = WBFLAG_RECURSE;
- if (winbindd_request_response(WINBINDD_PRIV_PIPE_DIR, &request, &response) == NSS_STATUS_SUCCESS) {
- int fd;
- if ((fd = winbind_named_pipe_sock((char *)response.extra_data.data)) != -1) {
- close(winbindd_fd);
- winbindd_fd = fd;
- is_privileged = 1;
- }
- }
-
- if ((need_priv != 0) && (is_privileged == 0)) {
- return -1;
- }
-
- SAFE_FREE(response.extra_data.data);
-
- return winbindd_fd;
-#else
- return -1;
-#endif /* HAVE_UNIXSOCKET */
-}
-
-/* Write data to winbindd socket */
-
-int winbind_write_sock(void *buffer, int count, int recursing, int need_priv)
-{
- int result, nwritten;
-
- /* Open connection to winbind daemon */
-
- restart:
-
- if (winbind_open_pipe_sock(recursing, need_priv) == -1) {
- errno = ENOENT;
- return -1;
- }
-
- /* Write data to socket */
-
- nwritten = 0;
-
- while(nwritten < count) {
- struct timeval tv;
- fd_set r_fds;
-
- /* Catch pipe close on other end by checking if a read()
- call would not block by calling select(). */
-
- FD_ZERO(&r_fds);
- FD_SET(winbindd_fd, &r_fds);
- ZERO_STRUCT(tv);
-
- if (select(winbindd_fd + 1, &r_fds, NULL, NULL, &tv) == -1) {
- winbind_close_sock();
- return -1; /* Select error */
- }
-
- /* Write should be OK if fd not available for reading */
-
- if (!FD_ISSET(winbindd_fd, &r_fds)) {
-
- /* Do the write */
-
- result = write(winbindd_fd,
- (char *)buffer + nwritten,
- count - nwritten);
-
- if ((result == -1) || (result == 0)) {
-
- /* Write failed */
-
- winbind_close_sock();
- return -1;
- }
-
- nwritten += result;
-
- } else {
-
- /* Pipe has closed on remote end */
-
- winbind_close_sock();
- goto restart;
- }
- }
-
- return nwritten;
-}
-
-/* Read data from winbindd socket */
-
-int winbind_read_sock(void *buffer, int count)
-{
- int nread = 0;
- int total_time = 0, selret;
-
- if (winbindd_fd == -1) {
- return -1;
- }
-
- /* Read data from socket */
- while(nread < count) {
- struct timeval tv;
- fd_set r_fds;
-
- /* Catch pipe close on other end by checking if a read()
- call would not block by calling select(). */
-
- FD_ZERO(&r_fds);
- FD_SET(winbindd_fd, &r_fds);
- ZERO_STRUCT(tv);
- /* Wait for 5 seconds for a reply. May need to parameterise this... */
- tv.tv_sec = 5;
-
- if ((selret = select(winbindd_fd + 1, &r_fds, NULL, NULL, &tv)) == -1) {
- winbind_close_sock();
- return -1; /* Select error */
- }
-
- if (selret == 0) {
- /* Not ready for read yet... */
- if (total_time >= 30) {
- /* Timeout */
- winbind_close_sock();
- return -1;
- }
- total_time += 5;
- continue;
- }
-
- if (FD_ISSET(winbindd_fd, &r_fds)) {
-
- /* Do the Read */
-
- int result = read(winbindd_fd, (char *)buffer + nread,
- count - nread);
-
- if ((result == -1) || (result == 0)) {
-
- /* Read failed. I think the only useful thing we
- can do here is just return -1 and fail since the
- transaction has failed half way through. */
-
- winbind_close_sock();
- return -1;
- }
-
- nread += result;
-
- }
- }
-
- return nread;
-}
-
-/* Read reply */
-
-int winbindd_read_reply(struct winbindd_response *response)
-{
- int result1, result2 = 0;
-
- if (!response) {
- return -1;
- }
-
- /* Read fixed length response */
-
- result1 = winbind_read_sock(response,
- sizeof(struct winbindd_response));
- if (result1 == -1) {
- return -1;
- }
-
- /* We actually send the pointer value of the extra_data field from
- the server. This has no meaning in the client's address space
- so we clear it out. */
-
- response->extra_data.data = NULL;
-
- /* Read variable length response */
-
- if (response->length > sizeof(struct winbindd_response)) {
- int extra_data_len = response->length -
- sizeof(struct winbindd_response);
-
- /* Mallocate memory for extra data */
-
- if (!(response->extra_data.data = malloc(extra_data_len))) {
- return -1;
- }
-
- result2 = winbind_read_sock(response->extra_data.data,
- extra_data_len);
- if (result2 == -1) {
- winbindd_free_response(response);
- return -1;
- }
- }
-
- /* Return total amount of data read */
-
- return result1 + result2;
-}
-
-/*
- * send simple types of requests
- */
-
-NSS_STATUS winbindd_send_request(int req_type, int need_priv,
- struct winbindd_request *request)
-{
- struct winbindd_request lrequest;
-
- /* Check for our tricky environment variable */
-
- if (winbind_env_set()) {
- return NSS_STATUS_NOTFOUND;
- }
-
- if (!request) {
- ZERO_STRUCT(lrequest);
- request = &lrequest;
- }
-
- /* Fill in request and send down pipe */
-
- winbindd_init_request(request, req_type);
-
- if (winbind_write_sock(request, sizeof(*request),
- request->wb_flags & WBFLAG_RECURSE,
- need_priv) == -1)
- {
- /* Set ENOENT for consistency. Required by some apps */
- errno = ENOENT;
-
- return NSS_STATUS_UNAVAIL;
- }
-
- if ((request->extra_len != 0) &&
- (winbind_write_sock(request->extra_data.data,
- request->extra_len,
- request->wb_flags & WBFLAG_RECURSE,
- need_priv) == -1))
- {
- /* Set ENOENT for consistency. Required by some apps */
- errno = ENOENT;
-
- return NSS_STATUS_UNAVAIL;
- }
-
- return NSS_STATUS_SUCCESS;
-}
-
-/*
- * Get results from winbindd request
- */
-
-NSS_STATUS winbindd_get_response(struct winbindd_response *response)
-{
- struct winbindd_response lresponse;
-
- if (!response) {
- ZERO_STRUCT(lresponse);
- response = &lresponse;
- }
-
- init_response(response);
-
- /* Wait for reply */
- if (winbindd_read_reply(response) == -1) {
- /* Set ENOENT for consistency. Required by some apps */
- errno = ENOENT;
-
- return NSS_STATUS_UNAVAIL;
- }
-
- /* Throw away extra data if client didn't request it */
- if (response == &lresponse) {
- winbindd_free_response(response);
- }
-
- /* Copy reply data from socket */
- if (response->result != WINBINDD_OK) {
- return NSS_STATUS_NOTFOUND;
- }
-
- return NSS_STATUS_SUCCESS;
-}
-
-/* Handle simple types of requests */
-
-NSS_STATUS winbindd_request_response(int req_type,
- struct winbindd_request *request,
- struct winbindd_response *response)
-{
- NSS_STATUS status = NSS_STATUS_UNAVAIL;
- int count = 0;
-
- while ((status == NSS_STATUS_UNAVAIL) && (count < 10)) {
- status = winbindd_send_request(req_type, 0, request);
- if (status != NSS_STATUS_SUCCESS)
- return(status);
- status = winbindd_get_response(response);
- count += 1;
- }
-
- return status;
-}
-
-NSS_STATUS winbindd_priv_request_response(int req_type,
- struct winbindd_request *request,
- struct winbindd_response *response)
-{
- NSS_STATUS status = NSS_STATUS_UNAVAIL;
- int count = 0;
-
- while ((status == NSS_STATUS_UNAVAIL) && (count < 10)) {
- status = winbindd_send_request(req_type, 1, request);
- if (status != NSS_STATUS_SUCCESS)
- return(status);
- status = winbindd_get_response(response);
- count += 1;
- }
-
- return status;
-}
-
-/*************************************************************************
- ************************************************************************/
-
-const char *nss_err_str(NSS_STATUS ret)
-{
- switch (ret) {
- case NSS_STATUS_TRYAGAIN:
- return "NSS_STATUS_TRYAGAIN";
- case NSS_STATUS_SUCCESS:
- return "NSS_STATUS_SUCCESS";
- case NSS_STATUS_NOTFOUND:
- return "NSS_STATUS_NOTFOUND";
- case NSS_STATUS_UNAVAIL:
- return "NSS_STATUS_UNAVAIL";
-#ifdef NSS_STATUS_RETURN
- case NSS_STATUS_RETURN:
- return "NSS_STATUS_RETURN";
-#endif
- default:
- return "UNKNOWN RETURN CODE!!!!!!!";
- }
-}
diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c
deleted file mode 100644
index c85e210cc0..0000000000
--- a/source3/nsswitch/wbinfo.c
+++ /dev/null
@@ -1,1984 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind status program.
-
- Copyright (C) Tim Potter 2000-2003
- Copyright (C) Andrew Bartlett 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 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 "includes.h"
-#include "winbind_client.h"
-#include "libwbclient/wbclient.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-static struct wbcInterfaceDetails *init_interface_details(void)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- static struct wbcInterfaceDetails *details;
-
- if (details) {
- return details;
- }
-
- wbc_status = wbcInterfaceDetails(&details);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- d_fprintf(stderr, "could not obtain winbind interface details!\n");
- }
-
- return details;
-}
-
-static char winbind_separator_int(bool strict)
-{
- struct wbcInterfaceDetails *details;
- static bool got_sep;
- static char sep;
-
- if (got_sep)
- return sep;
-
- details = init_interface_details();
-
- if (!details) {
- d_fprintf(stderr, "could not obtain winbind separator!\n");
- if (strict) {
- return 0;
- }
- /* HACK: (this module should not call lp_ funtions) */
- return *lp_winbind_separator();
- }
-
- sep = details->winbind_separator;
- got_sep = true;
-
- if (!sep) {
- d_fprintf(stderr, "winbind separator was NULL!\n");
- if (strict) {
- return 0;
- }
- /* HACK: (this module should not call lp_ funtions) */
- sep = *lp_winbind_separator();
- }
-
- return sep;
-}
-
-static char winbind_separator(void)
-{
- return winbind_separator_int(false);
-}
-
-static const char *get_winbind_domain(void)
-{
- static struct wbcInterfaceDetails *details;
-
- details = init_interface_details();
-
- if (!details) {
- d_fprintf(stderr, "could not obtain winbind domain name!\n");
-
- /* HACK: (this module should not call lp_ functions) */
- return lp_workgroup();
- }
-
- return details->netbios_domain;
-}
-
-/* Copy of parse_domain_user from winbindd_util.c. Parse a string of the
- form DOMAIN/user into a domain and a user */
-
-static bool parse_wbinfo_domain_user(const char *domuser, fstring domain,
- fstring user)
-{
-
- char *p = strchr(domuser,winbind_separator());
-
- if (!p) {
- /* Maybe it was a UPN? */
- if ((p = strchr(domuser, '@')) != NULL) {
- fstrcpy(domain, "");
- fstrcpy(user, domuser);
- return true;
- }
-
- fstrcpy(user, domuser);
- fstrcpy(domain, get_winbind_domain());
- return true;
- }
-
- fstrcpy(user, p+1);
- fstrcpy(domain, domuser);
- domain[PTR_DIFF(p, domuser)] = 0;
- strupper_m(domain);
-
- return true;
-}
-
-/* Parse string of "uid,sid" or "gid,sid" into separate int and string values.
- * Return true if input was valid, false otherwise. */
-static bool parse_mapping_arg(char *arg, int *id, char **sid)
-{
- char *tmp, *endptr;
-
- if (!arg || !*arg)
- return false;
-
- tmp = strtok(arg, ",");
- *sid = strtok(NULL, ",");
-
- if (!tmp || !*tmp || !*sid || !**sid)
- return false;
-
- /* Because atoi() can return 0 on invalid input, which would be a valid
- * UID/GID we must use strtoul() and do error checking */
- *id = strtoul(tmp, &endptr, 10);
-
- if (endptr[0] != '\0')
- return false;
-
- return true;
-}
-
-/* pull pwent info for a given user */
-
-static bool wbinfo_get_userinfo(char *user)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct passwd *pwd = NULL;
-
- wbc_status = wbcGetpwnam(user, &pwd);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- d_printf("%s:%s:%d:%d:%s:%s:%s\n",
- pwd->pw_name,
- pwd->pw_passwd,
- pwd->pw_uid,
- pwd->pw_gid,
- pwd->pw_gecos,
- pwd->pw_dir,
- pwd->pw_shell);
-
- return true;
-}
-
-/* pull pwent info for a given uid */
-static bool wbinfo_get_uidinfo(int uid)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct passwd *pwd = NULL;
-
- wbc_status = wbcGetpwuid(uid, &pwd);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- d_printf("%s:%s:%d:%d:%s:%s:%s\n",
- pwd->pw_name,
- pwd->pw_passwd,
- pwd->pw_uid,
- pwd->pw_gid,
- pwd->pw_gecos,
- pwd->pw_dir,
- pwd->pw_shell);
-
- return true;
-}
-
-/* pull grent for a given group */
-static bool wbinfo_get_groupinfo(const char *group)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct group *grp;
-
- wbc_status = wbcGetgrnam(group, &grp);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- d_printf("%s:%s:%d\n",
- grp->gr_name,
- grp->gr_passwd,
- grp->gr_gid);
-
- wbcFreeMemory(grp);
-
- return true;
-}
-
-/* List groups a user is a member of */
-
-static bool wbinfo_get_usergroups(const char *user)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- uint32_t num_groups;
- uint32_t i;
- gid_t *groups = NULL;
-
- /* Send request */
-
- wbc_status = wbcGetGroups(user, &num_groups, &groups);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- for (i = 0; i < num_groups; i++) {
- d_printf("%d\n", (int)groups[i]);
- }
-
- wbcFreeMemory(groups);
-
- return true;
-}
-
-
-/* List group SIDs a user SID is a member of */
-static bool wbinfo_get_usersids(const char *user_sid_str)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- uint32_t num_sids;
- uint32_t i;
- struct wbcDomainSid user_sid, *sids = NULL;
-
- /* Send request */
-
- wbc_status = wbcStringToSid(user_sid_str, &user_sid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- wbc_status = wbcLookupUserSids(&user_sid, false, &num_sids, &sids);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- for (i = 0; i < num_sids; i++) {
- char *str = NULL;
- wbc_status = wbcSidToString(&sids[i], &str);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- wbcFreeMemory(sids);
- return false;
- }
- d_printf("%s\n", str);
- wbcFreeMemory(str);
- }
-
- wbcFreeMemory(sids);
-
- return true;
-}
-
-static bool wbinfo_get_userdomgroups(const char *user_sid_str)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- uint32_t num_sids;
- uint32_t i;
- struct wbcDomainSid user_sid, *sids = NULL;
-
- /* Send request */
-
- wbc_status = wbcStringToSid(user_sid_str, &user_sid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- wbc_status = wbcLookupUserSids(&user_sid, true, &num_sids, &sids);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- for (i = 0; i < num_sids; i++) {
- char *str = NULL;
- wbc_status = wbcSidToString(&sids[i], &str);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- wbcFreeMemory(sids);
- return false;
- }
- d_printf("%s\n", str);
- wbcFreeMemory(str);
- }
-
- wbcFreeMemory(sids);
-
- return true;
-}
-
-/* Convert NetBIOS name to IP */
-
-static bool wbinfo_wins_byname(const char *name)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *ip = NULL;
-
- wbc_status = wbcResolveWinsByName(name, &ip);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- /* Display response */
-
- d_printf("%s\n", ip);
-
- wbcFreeMemory(ip);
-
- return true;
-}
-
-/* Convert IP to NetBIOS name */
-
-static bool wbinfo_wins_byip(const char *ip)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *name = NULL;
-
- wbc_status = wbcResolveWinsByIP(ip, &name);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- /* Display response */
-
- d_printf("%s\n", name);
-
- wbcFreeMemory(name);
-
- return true;
-}
-
-/* List all/trusted domains */
-
-static bool wbinfo_list_domains(bool list_all_domains, bool verbose)
-{
- struct wbcDomainInfo *domain_list = NULL;
- size_t num_domains;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- bool print_all = !list_all_domains && verbose;
- int i;
-
- wbc_status = wbcListTrusts(&domain_list, &num_domains);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- if (print_all) {
- d_printf("%-16s%-24s%-12s%-12s%-5s%-5s\n",
- "Domain Name", "DNS Domain", "Trust Type",
- "Transitive", "In", "Out");
- }
-
- for (i=0; i<num_domains; i++) {
- if (print_all) {
- d_printf("%-16s", domain_list[i].short_name);
- } else {
- d_printf("%s", domain_list[i].short_name);
- d_printf("\n");
- continue;
- }
-
- d_printf("%-24s", domain_list[i].dns_name);
-
- switch(domain_list[i].trust_type) {
- case WBC_DOMINFO_TRUSTTYPE_NONE:
- d_printf("None ");
- break;
- case WBC_DOMINFO_TRUSTTYPE_FOREST:
- d_printf("Forest ");
- break;
- case WBC_DOMINFO_TRUSTTYPE_EXTERNAL:
- d_printf("External ");
- break;
- case WBC_DOMINFO_TRUSTTYPE_IN_FOREST:
- d_printf("In-Forest ");
- break;
- }
-
- if (domain_list[i].trust_flags & WBC_DOMINFO_TRUST_TRANSITIVE) {
- d_printf("Yes ");
- } else {
- d_printf("No ");
- }
-
- if (domain_list[i].trust_flags & WBC_DOMINFO_TRUST_INCOMING) {
- d_printf("Yes ");
- } else {
- d_printf("No ");
- }
-
- if (domain_list[i].trust_flags & WBC_DOMINFO_TRUST_OUTGOING) {
- d_printf("Yes ");
- } else {
- d_printf("No ");
- }
-
- d_printf("\n");
- }
-
- return true;
-}
-
-/* List own domain */
-
-static bool wbinfo_list_own_domain(void)
-{
- d_printf("%s\n", get_winbind_domain());
-
- return true;
-}
-
-/* show sequence numbers */
-static bool wbinfo_show_sequence(const char *domain)
-{
- d_printf("This command has been deprecated. Please use the --online-status option instead.\n");
- return false;
-}
-
-/* show sequence numbers */
-static bool wbinfo_show_onlinestatus(const char *domain)
-{
- struct wbcDomainInfo *domain_list = NULL;
- size_t num_domains;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- int i;
-
- wbc_status = wbcListTrusts(&domain_list, &num_domains);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- for (i=0; i<num_domains; i++) {
- bool is_offline;
-
- if (domain) {
- if (!strequal(domain_list[i].short_name, domain)) {
- continue;
- }
- }
-
- is_offline = (domain_list[i].domain_flags & WBC_DOMINFO_DOMAIN_OFFLINE);
-
- d_printf("%s : %s\n",
- domain_list[i].short_name,
- is_offline ? "offline" : "online" );
- }
-
- return true;
-}
-
-
-/* Show domain info */
-
-static bool wbinfo_domain_info(const char *domain)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcDomainInfo *dinfo = NULL;
- char *sid_str = NULL;
-
- if ((domain == NULL) || (strequal(domain, ".")) || (domain[0] == '\0')) {
- domain = get_winbind_domain();
- }
-
- /* Send request */
-
- wbc_status = wbcDomainInfo(domain, &dinfo);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- wbc_status = wbcSidToString(&dinfo->sid, &sid_str);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- wbcFreeMemory(dinfo);
- return false;
- }
-
- /* Display response */
-
- d_printf("Name : %s\n", dinfo->short_name);
- d_printf("Alt_Name : %s\n", dinfo->dns_name);
-
- d_printf("SID : %s\n", sid_str);
-
- d_printf("Active Directory : %s\n",
- (dinfo->domain_flags & WBC_DOMINFO_DOMAIN_AD) ? "Yes" : "No");
- d_printf("Native : %s\n",
- (dinfo->domain_flags & WBC_DOMINFO_DOMAIN_NATIVE) ? "Yes" : "No");
-
- d_printf("Primary : %s\n",
- (dinfo->domain_flags & WBC_DOMINFO_DOMAIN_PRIMARY) ? "Yes" : "No");
-
- wbcFreeMemory(sid_str);
- wbcFreeMemory(dinfo);
-
- return true;
-}
-
-/* Get a foreign DC's name */
-static bool wbinfo_getdcname(const char *domain_name)
-{
- struct winbindd_request request;
- struct winbindd_response response;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- fstrcpy(request.domain_name, domain_name);
-
- /* Send request */
-
- if (winbindd_request_response(WINBINDD_GETDCNAME, &request, &response) !=
- NSS_STATUS_SUCCESS) {
- d_fprintf(stderr, "Could not get dc name for %s\n", domain_name);
- return false;
- }
-
- /* Display response */
-
- d_printf("%s\n", response.data.dc_name);
-
- return true;
-}
-
-/* Find a DC */
-static bool wbinfo_dsgetdcname(const char *domain_name, uint32_t flags)
-{
- struct winbindd_request request;
- struct winbindd_response response;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- fstrcpy(request.data.dsgetdcname.domain_name, domain_name);
- request.data.dsgetdcname.flags = flags;
-
- request.flags |= DS_DIRECTORY_SERVICE_REQUIRED;
-
- /* Send request */
-
- if (winbindd_request_response(WINBINDD_DSGETDCNAME, &request, &response) !=
- NSS_STATUS_SUCCESS) {
- d_fprintf(stderr, "Could not find dc for %s\n", domain_name);
- return false;
- }
-
- /* Display response */
-
- d_printf("%s\n", response.data.dsgetdcname.dc_unc);
- d_printf("%s\n", response.data.dsgetdcname.dc_address);
- d_printf("%d\n", response.data.dsgetdcname.dc_address_type);
- d_printf("%s\n", response.data.dsgetdcname.domain_guid);
- d_printf("%s\n", response.data.dsgetdcname.domain_name);
- d_printf("%s\n", response.data.dsgetdcname.forest_name);
- d_printf("0x%08x\n", response.data.dsgetdcname.dc_flags);
- d_printf("%s\n", response.data.dsgetdcname.dc_site_name);
- d_printf("%s\n", response.data.dsgetdcname.client_site_name);
-
- return true;
-}
-
-/* Check trust account password */
-
-static bool wbinfo_check_secret(void)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcAuthErrorInfo *error = NULL;
-
- wbc_status = wbcCheckTrustCredentials(NULL, &error);
-
- d_printf("checking the trust secret via RPC calls %s\n",
- WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
-
- if (wbc_status == WBC_ERR_AUTH_ERROR) {
- d_fprintf(stderr, "error code was %s (0x%x)\n",
- error->nt_string, error->nt_status);
- wbcFreeMemory(error);
- }
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- return true;
-}
-
-/* Convert uid to sid */
-
-static bool wbinfo_uid_to_sid(uid_t uid)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcDomainSid sid;
- char *sid_str = NULL;
-
- /* Send request */
-
- wbc_status = wbcUidToSid(uid, &sid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- wbc_status = wbcSidToString(&sid, &sid_str);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- /* Display response */
-
- d_printf("%s\n", sid_str);
-
- wbcFreeMemory(sid_str);
-
- return true;
-}
-
-/* Convert gid to sid */
-
-static bool wbinfo_gid_to_sid(gid_t gid)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcDomainSid sid;
- char *sid_str = NULL;
-
- /* Send request */
-
- wbc_status = wbcGidToSid(gid, &sid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- wbc_status = wbcSidToString(&sid, &sid_str);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- /* Display response */
-
- d_printf("%s\n", sid_str);
-
- wbcFreeMemory(sid_str);
-
- return true;
-}
-
-/* Convert sid to uid */
-
-static bool wbinfo_sid_to_uid(const char *sid_str)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcDomainSid sid;
- uid_t uid;
-
- /* Send request */
-
- wbc_status = wbcStringToSid(sid_str, &sid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- wbc_status = wbcSidToUid(&sid, &uid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- /* Display response */
-
- d_printf("%d\n", (int)uid);
-
- return true;
-}
-
-static bool wbinfo_sid_to_gid(const char *sid_str)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcDomainSid sid;
- gid_t gid;
-
- /* Send request */
-
- wbc_status = wbcStringToSid(sid_str, &sid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- wbc_status = wbcSidToGid(&sid, &gid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- /* Display response */
-
- d_printf("%d\n", (int)gid);
-
- return true;
-}
-
-static bool wbinfo_allocate_uid(void)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- uid_t uid;
-
- /* Send request */
-
- wbc_status = wbcAllocateUid(&uid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- /* Display response */
-
- d_printf("New uid: %d\n", uid);
-
- return true;
-}
-
-static bool wbinfo_allocate_gid(void)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- gid_t gid;
-
- /* Send request */
-
- wbc_status = wbcAllocateGid(&gid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- /* Display response */
-
- d_printf("New gid: %d\n", gid);
-
- return true;
-}
-
-static bool wbinfo_set_uid_mapping(uid_t uid, const char *sid_str)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcDomainSid sid;
-
- /* Send request */
-
- wbc_status = wbcStringToSid(sid_str, &sid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- wbc_status = wbcSetUidMapping(uid, &sid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- /* Display response */
-
- d_printf("uid %d now mapped to sid %s\n", uid, sid_str);
-
- return true;
-}
-
-static bool wbinfo_set_gid_mapping(gid_t gid, const char *sid_str)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcDomainSid sid;
-
- /* Send request */
-
- wbc_status = wbcStringToSid(sid_str, &sid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- wbc_status = wbcSetGidMapping(gid, &sid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- /* Display response */
-
- d_printf("gid %d now mapped to sid %s\n", gid, sid_str);
-
- return true;
-}
-
-static bool wbinfo_remove_uid_mapping(uid_t uid, const char *sid_str)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcDomainSid sid;
-
- /* Send request */
-
- wbc_status = wbcStringToSid(sid_str, &sid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- wbc_status = wbcRemoveUidMapping(uid, &sid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- /* Display response */
-
- d_printf("Removed uid %d to sid %s mapping\n", uid, sid_str);
-
- return true;
-}
-
-static bool wbinfo_remove_gid_mapping(gid_t gid, const char *sid_str)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcDomainSid sid;
-
- /* Send request */
-
- wbc_status = wbcStringToSid(sid_str, &sid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- wbc_status = wbcRemoveGidMapping(gid, &sid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- /* Display response */
-
- d_printf("Removed gid %d to sid %s mapping\n", gid, sid_str);
-
- return true;
-}
-
-/* Convert sid to string */
-
-static bool wbinfo_lookupsid(const char *sid_str)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcDomainSid sid;
- char *domain;
- char *name;
- enum wbcSidType type;
-
- /* Send off request */
-
- wbc_status = wbcStringToSid(sid_str, &sid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- wbc_status = wbcLookupSid(&sid, &domain, &name, &type);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- /* Display response */
-
- d_printf("%s%c%s %d\n",
- domain, winbind_separator(), name, type);
-
- return true;
-}
-
-/* Convert sid to fullname */
-
-static bool wbinfo_lookupsid_fullname(const char *sid_str)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcDomainSid sid;
- char *domain;
- char *name;
- enum wbcSidType type;
-
- /* Send off request */
-
- wbc_status = wbcStringToSid(sid_str, &sid);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- wbc_status = wbcGetDisplayName(&sid, &domain, &name, &type);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- /* Display response */
-
- d_printf("%s%c%s %d\n",
- domain, winbind_separator(), name, type);
-
- return true;
-}
-
-/* Lookup a list of RIDs */
-
-static bool wbinfo_lookuprids(const char *domain, const char *arg)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcDomainInfo *dinfo = NULL;
- char *domain_name = NULL;
- const char **names = NULL;
- enum wbcSidType *types = NULL;
- size_t i;
- int num_rids;
- uint32 *rids = NULL;
- const char *p;
- char *ridstr;
- TALLOC_CTX *mem_ctx = NULL;
- bool ret = false;
-
- if ((domain == NULL) || (strequal(domain, ".")) || (domain[0] == '\0')) {
- domain = get_winbind_domain();
- }
-
- /* Send request */
-
- wbc_status = wbcDomainInfo(domain, &dinfo);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- d_printf("wbcDomainInfo(%s) failed: %s\n", domain,
- wbcErrorString(wbc_status));
- goto done;
- }
-
- mem_ctx = talloc_new(NULL);
- if (mem_ctx == NULL) {
- d_printf("talloc_new failed\n");
- goto done;
- }
-
- num_rids = 0;
- rids = NULL;
- p = arg;
-
- while (next_token_talloc(mem_ctx, &p, &ridstr, " ,\n")) {
- uint32 rid = strtoul(ridstr, NULL, 10);
- ADD_TO_ARRAY(mem_ctx, uint32, rid, &rids, &num_rids);
- }
-
- if (rids == NULL) {
- d_printf("no rids\n");
- goto done;
- }
-
- wbc_status = wbcLookupRids(&dinfo->sid, num_rids, rids,
- (const char **)&domain_name, &names, &types);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- d_printf("winbind_lookup_rids failed: %s\n",
- wbcErrorString(wbc_status));
- goto done;
- }
-
- d_printf("Domain: %s\n", domain_name);
-
- for (i=0; i<num_rids; i++) {
- d_printf("%8d: %s (%s)\n", rids[i], names[i],
- sid_type_lookup(types[i]));
- }
-
- ret = true;
-done:
- if (dinfo) {
- wbcFreeMemory(dinfo);
- }
- if (domain_name) {
- wbcFreeMemory(domain_name);
- }
- if (names) {
- wbcFreeMemory(names);
- }
- if (types) {
- wbcFreeMemory(types);
- }
- TALLOC_FREE(mem_ctx);
- return ret;
-}
-
-/* Convert string to sid */
-
-static bool wbinfo_lookupname(const char *full_name)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcDomainSid sid;
- char *sid_str;
- enum wbcSidType type;
- fstring domain_name;
- fstring account_name;
-
- /* Send off request */
-
- parse_wbinfo_domain_user(full_name, domain_name,
- account_name);
-
- wbc_status = wbcLookupName(domain_name, account_name,
- &sid, &type);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- wbc_status = wbcSidToString(&sid, &sid_str);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- /* Display response */
-
- d_printf("%s %s (%d)\n", sid_str, sid_type_lookup(type), type);
-
- wbcFreeMemory(sid_str);
-
- return true;
-}
-
-static char *wbinfo_prompt_pass(const char *prefix,
- const char *username)
-{
- char *prompt;
- const char *ret = NULL;
-
- prompt = talloc_asprintf(talloc_tos(), "Enter %s's ", username);
- if (!prompt) {
- return NULL;
- }
- if (prefix) {
- prompt = talloc_asprintf_append(prompt, "%s ", prefix);
- if (!prompt) {
- return NULL;
- }
- }
- prompt = talloc_asprintf_append(prompt, "password: ");
- if (!prompt) {
- return NULL;
- }
-
- ret = getpass(prompt);
- TALLOC_FREE(prompt);
-
- return SMB_STRDUP(ret);
-}
-
-/* Authenticate a user with a plaintext password */
-
-static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32 flags)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
- char *p;
- char *password;
-
- /* Send off request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- p = strchr(username, '%');
-
- if (p) {
- *p = 0;
- fstrcpy(request.data.auth.user, username);
- fstrcpy(request.data.auth.pass, p + 1);
- *p = '%';
- } else {
- fstrcpy(request.data.auth.user, username);
- password = wbinfo_prompt_pass(NULL, username);
- fstrcpy(request.data.auth.pass, password);
- SAFE_FREE(password);
- }
-
- request.flags = flags;
-
- fstrcpy(request.data.auth.krb5_cc_type, cctype);
-
- request.data.auth.uid = geteuid();
-
- result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response);
-
- /* Display response */
-
- d_printf("plaintext kerberos password authentication for [%s] %s (requesting cctype: %s)\n",
- username, (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed", cctype);
-
- if (response.data.auth.nt_status)
- d_fprintf(stderr, "error code was %s (0x%x)\nerror messsage was: %s\n",
- response.data.auth.nt_status_string,
- response.data.auth.nt_status,
- response.data.auth.error_string);
-
- if (result == NSS_STATUS_SUCCESS) {
-
- if (request.flags & WBFLAG_PAM_INFO3_TEXT) {
- if (response.data.auth.info3.user_flgs & NETLOGON_CACHED_ACCOUNT) {
- d_printf("user_flgs: NETLOGON_CACHED_ACCOUNT\n");
- }
- }
-
- if (response.data.auth.krb5ccname[0] != '\0') {
- d_printf("credentials were put in: %s\n", response.data.auth.krb5ccname);
- } else {
- d_printf("no credentials cached\n");
- }
- }
-
- return result == NSS_STATUS_SUCCESS;
-}
-
-/* Authenticate a user with a plaintext password */
-
-static bool wbinfo_auth(char *username)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *s = NULL;
- char *p = NULL;
- char *password = NULL;
- char *name = NULL;
-
- if ((s = SMB_STRDUP(username)) == NULL) {
- return false;
- }
-
- if ((p = strchr(s, '%')) != NULL) {
- *p = 0;
- p++;
- password = SMB_STRDUP(p);
- } else {
- password = wbinfo_prompt_pass(NULL, username);
- }
-
- name = s;
-
- wbc_status = wbcAuthenticateUser(name, password);
-
- d_printf("plaintext password authentication %s\n",
- WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
-
-#if 0
- if (response.data.auth.nt_status)
- d_fprintf(stderr, "error code was %s (0x%x)\nerror messsage was: %s\n",
- response.data.auth.nt_status_string,
- response.data.auth.nt_status,
- response.data.auth.error_string);
-#endif
-
- SAFE_FREE(s);
- SAFE_FREE(password);
-
- return WBC_ERROR_IS_OK(wbc_status);
-}
-
-/* Authenticate a user with a challenge/response */
-
-static bool wbinfo_auth_crap(char *username)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct wbcAuthUserParams params;
- struct wbcAuthUserInfo *info = NULL;
- struct wbcAuthErrorInfo *err = NULL;
- DATA_BLOB lm = data_blob_null;
- DATA_BLOB nt = data_blob_null;
- fstring name_user;
- fstring name_domain;
- char *pass;
- char *p;
-
- p = strchr(username, '%');
-
- if (p) {
- *p = 0;
- pass = SMB_STRDUP(p + 1);
- } else {
- pass = wbinfo_prompt_pass(NULL, username);
- }
-
- parse_wbinfo_domain_user(username, name_domain, name_user);
-
- params.account_name = name_user;
- params.domain_name = name_domain;
- params.workstation_name = NULL;
-
- params.flags = 0;
- params.parameter_control= WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT |
- WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT;
-
- params.level = WBC_AUTH_USER_LEVEL_RESPONSE;
-
- generate_random_buffer(params.password.response.challenge, 8);
-
- if (lp_client_ntlmv2_auth()) {
- DATA_BLOB server_chal;
- DATA_BLOB names_blob;
-
- server_chal = data_blob(params.password.response.challenge, 8);
-
- /* Pretend this is a login to 'us', for blob purposes */
- names_blob = NTLMv2_generate_names_blob(global_myname(), lp_workgroup());
-
- if (!SMBNTLMv2encrypt(name_user, name_domain, pass, &server_chal,
- &names_blob,
- &lm, &nt, NULL)) {
- data_blob_free(&names_blob);
- data_blob_free(&server_chal);
- SAFE_FREE(pass);
- return false;
- }
- data_blob_free(&names_blob);
- data_blob_free(&server_chal);
-
- } else {
- if (lp_client_lanman_auth()) {
- bool ok;
- lm = data_blob(NULL, 24);
- ok = SMBencrypt(pass, params.password.response.challenge,
- lm.data);
- if (!ok) {
- data_blob_free(&lm);
- }
- }
- nt = data_blob(NULL, 24);
- SMBNTencrypt(pass, params.password.response.challenge,
- nt.data);
- }
-
- params.password.response.nt_length = nt.length;
- params.password.response.nt_data = nt.data;
- params.password.response.lm_length = lm.length;
- params.password.response.lm_data = lm.data;
-
- wbc_status = wbcAuthenticateUserEx(&params, &info, &err);
-
- /* Display response */
-
- d_printf("challenge/response password authentication %s\n",
- WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
-
- if (wbc_status == WBC_ERR_AUTH_ERROR) {
- d_fprintf(stderr, "error code was %s (0x%x)\nerror messsage was: %s\n",
- err->nt_string,
- err->nt_status,
- err->display_string);
- wbcFreeMemory(err);
- } else if (WBC_ERROR_IS_OK(wbc_status)) {
- wbcFreeMemory(info);
- }
-
- data_blob_free(&nt);
- data_blob_free(&lm);
- SAFE_FREE(pass);
-
- return WBC_ERROR_IS_OK(wbc_status);
-}
-
-/* Authenticate a user with a plaintext password and set a token */
-
-static bool wbinfo_klog(char *username)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
- char *p;
-
- /* Send off request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- p = strchr(username, '%');
-
- if (p) {
- *p = 0;
- fstrcpy(request.data.auth.user, username);
- fstrcpy(request.data.auth.pass, p + 1);
- *p = '%';
- } else {
- fstrcpy(request.data.auth.user, username);
- fstrcpy(request.data.auth.pass, getpass("Password: "));
- }
-
- request.flags |= WBFLAG_PAM_AFS_TOKEN;
-
- result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response);
-
- /* Display response */
-
- d_printf("plaintext password authentication %s\n",
- (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
-
- if (response.data.auth.nt_status)
- d_fprintf(stderr, "error code was %s (0x%x)\nerror messsage was: %s\n",
- response.data.auth.nt_status_string,
- response.data.auth.nt_status,
- response.data.auth.error_string);
-
- if (result != NSS_STATUS_SUCCESS)
- return false;
-
- if (response.extra_data.data == NULL) {
- d_fprintf(stderr, "Did not get token data\n");
- return false;
- }
-
- if (!afs_settoken_str((char *)response.extra_data.data)) {
- d_fprintf(stderr, "Could not set token\n");
- return false;
- }
-
- d_printf("Successfully created AFS token\n");
- return true;
-}
-
-/* Print domain users */
-
-static bool print_domain_users(const char *domain)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- uint32_t i;
- uint32_t num_users = 0;
- const char **users = NULL;
-
- /* Send request to winbind daemon */
-
- /* '.' is the special sign for our own domain */
- if (domain && strcmp(domain, ".") == 0) {
- domain = get_winbind_domain();
- }
-
- wbc_status = wbcListUsers(domain, &num_users, &users);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- for (i=0; i < num_users; i++) {
- d_printf("%s\n", users[i]);
- }
-
- wbcFreeMemory(users);
-
- return true;
-}
-
-/* Print domain groups */
-
-static bool print_domain_groups(const char *domain)
-{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- uint32_t i;
- uint32_t num_groups = 0;
- const char **groups = NULL;
-
- /* Send request to winbind daemon */
-
- /* '.' is the special sign for our own domain */
- if (domain && strcmp(domain, ".") == 0) {
- domain = get_winbind_domain();
- }
-
- wbc_status = wbcListGroups(domain, &num_groups, &groups);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- for (i=0; i < num_groups; i++) {
- d_printf("%s\n", groups[i]);
- }
-
- wbcFreeMemory(groups);
-
- return true;
-}
-
-/* Set the authorised user for winbindd access in secrets.tdb */
-
-static bool wbinfo_set_auth_user(char *username)
-{
- const char *password;
- char *p;
- fstring user, domain;
-
- /* Separate into user and password */
-
- parse_wbinfo_domain_user(username, domain, user);
-
- p = strchr(user, '%');
-
- if (p != NULL) {
- *p = 0;
- password = p+1;
- } else {
- char *thepass = getpass("Password: ");
- if (thepass) {
- password = thepass;
- } else
- password = "";
- }
-
- /* Store or remove DOMAIN\username%password in secrets.tdb */
-
- secrets_init();
-
- if (user[0]) {
-
- if (!secrets_store(SECRETS_AUTH_USER, user,
- strlen(user) + 1)) {
- d_fprintf(stderr, "error storing username\n");
- return false;
- }
-
- /* We always have a domain name added by the
- parse_wbinfo_domain_user() function. */
-
- if (!secrets_store(SECRETS_AUTH_DOMAIN, domain,
- strlen(domain) + 1)) {
- d_fprintf(stderr, "error storing domain name\n");
- return false;
- }
-
- } else {
- secrets_delete(SECRETS_AUTH_USER);
- secrets_delete(SECRETS_AUTH_DOMAIN);
- }
-
- if (password[0]) {
-
- if (!secrets_store(SECRETS_AUTH_PASSWORD, password,
- strlen(password) + 1)) {
- d_fprintf(stderr, "error storing password\n");
- return false;
- }
-
- } else
- secrets_delete(SECRETS_AUTH_PASSWORD);
-
- return true;
-}
-
-static void wbinfo_get_auth_user(void)
-{
- char *user, *domain, *password;
-
- /* Lift data from secrets file */
-
- secrets_fetch_ipc_userpass(&user, &domain, &password);
-
- if ((!user || !*user) && (!domain || !*domain ) && (!password || !*password)){
-
- SAFE_FREE(user);
- SAFE_FREE(domain);
- SAFE_FREE(password);
- d_printf("No authorised user configured\n");
- return;
- }
-
- /* Pretty print authorised user info */
-
- d_printf("%s%s%s%s%s\n", domain ? domain : "", domain ? lp_winbind_separator(): "",
- user, password ? "%" : "", password ? password : "");
-
- SAFE_FREE(user);
- SAFE_FREE(domain);
- SAFE_FREE(password);
-}
-
-static bool wbinfo_ping(void)
-{
- wbcErr wbc_status;
-
- wbc_status = wbcPing();
-
- /* Display response */
-
- d_printf("Ping to winbindd %s\n",
- WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
-
- return WBC_ERROR_IS_OK(wbc_status);
-}
-
-static bool wbinfo_change_user_password(const char *username)
-{
- wbcErr wbc_status;
- char *old_password = NULL;
- char *new_password = NULL;
-
- old_password = wbinfo_prompt_pass("old", username);
- new_password = wbinfo_prompt_pass("new", username);
-
- wbc_status = wbcChangeUserPassword(username, old_password, new_password);
-
- /* Display response */
-
- d_printf("Password change for user %s %s\n", username,
- WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
-
- SAFE_FREE(old_password);
- SAFE_FREE(new_password);
-
- return WBC_ERROR_IS_OK(wbc_status);
-}
-
-/* Main program */
-
-enum {
- OPT_SET_AUTH_USER = 1000,
- OPT_GET_AUTH_USER,
- OPT_DOMAIN_NAME,
- OPT_SEQUENCE,
- OPT_GETDCNAME,
- OPT_DSGETDCNAME,
- OPT_USERDOMGROUPS,
- OPT_USERSIDS,
- OPT_ALLOCATE_UID,
- OPT_ALLOCATE_GID,
- OPT_SET_UID_MAPPING,
- OPT_SET_GID_MAPPING,
- OPT_REMOVE_UID_MAPPING,
- OPT_REMOVE_GID_MAPPING,
- OPT_SEPARATOR,
- OPT_LIST_ALL_DOMAINS,
- OPT_LIST_OWN_DOMAIN,
- OPT_UID_INFO,
- OPT_GROUP_INFO,
- OPT_VERBOSE,
- OPT_ONLINESTATUS,
- OPT_CHANGE_USER_PASSWORD,
- OPT_SID_TO_FULLNAME
-};
-
-int main(int argc, char **argv, char **envp)
-{
- int opt;
- TALLOC_CTX *frame = talloc_stackframe();
- poptContext pc;
- static char *string_arg;
- char *string_subarg = NULL;
- static char *opt_domain_name;
- static int int_arg;
- int int_subarg = -1;
- int result = 1;
- bool verbose = false;
-
- struct poptOption long_options[] = {
- POPT_AUTOHELP
-
- /* longName, shortName, argInfo, argPtr, value, descrip,
- argDesc */
-
- { "domain-users", 'u', POPT_ARG_NONE, 0, 'u', "Lists all domain users", "domain"},
- { "domain-groups", 'g', POPT_ARG_NONE, 0, 'g', "Lists all domain groups", "domain" },
- { "WINS-by-name", 'N', POPT_ARG_STRING, &string_arg, 'N', "Converts NetBIOS name to IP", "NETBIOS-NAME" },
- { "WINS-by-ip", 'I', POPT_ARG_STRING, &string_arg, 'I', "Converts IP address to NetBIOS name", "IP" },
- { "name-to-sid", 'n', POPT_ARG_STRING, &string_arg, 'n', "Converts name to sid", "NAME" },
- { "sid-to-name", 's', POPT_ARG_STRING, &string_arg, 's', "Converts sid to name", "SID" },
- { "sid-to-fullname", 0, POPT_ARG_STRING, &string_arg,
- OPT_SID_TO_FULLNAME, "Converts sid to fullname", "SID" },
- { "lookup-rids", 'R', POPT_ARG_STRING, &string_arg, 'R', "Converts RIDs to names", "RIDs" },
- { "uid-to-sid", 'U', POPT_ARG_INT, &int_arg, 'U', "Converts uid to sid" , "UID" },
- { "gid-to-sid", 'G', POPT_ARG_INT, &int_arg, 'G', "Converts gid to sid", "GID" },
- { "sid-to-uid", 'S', POPT_ARG_STRING, &string_arg, 'S', "Converts sid to uid", "SID" },
- { "sid-to-gid", 'Y', POPT_ARG_STRING, &string_arg, 'Y', "Converts sid to gid", "SID" },
- { "allocate-uid", 0, POPT_ARG_NONE, 0, OPT_ALLOCATE_UID,
- "Get a new UID out of idmap" },
- { "allocate-gid", 0, POPT_ARG_NONE, 0, OPT_ALLOCATE_GID,
- "Get a new GID out of idmap" },
- { "set-uid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_SET_UID_MAPPING, "Create or modify uid to sid mapping in idmap", "UID,SID" },
- { "set-gid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_SET_GID_MAPPING, "Create or modify gid to sid mapping in idmap", "GID,SID" },
- { "remove-uid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_REMOVE_UID_MAPPING, "Remove uid to sid mapping in idmap", "UID,SID" },
- { "remove-gid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_REMOVE_GID_MAPPING, "Remove gid to sid mapping in idmap", "GID,SID" },
- { "check-secret", 't', POPT_ARG_NONE, 0, 't', "Check shared secret" },
- { "trusted-domains", 'm', POPT_ARG_NONE, 0, 'm', "List trusted domains" },
- { "all-domains", 0, POPT_ARG_NONE, 0, OPT_LIST_ALL_DOMAINS, "List all domains (trusted and own domain)" },
- { "own-domain", 0, POPT_ARG_NONE, 0, OPT_LIST_OWN_DOMAIN, "List own domain" },
- { "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE, "Show sequence numbers of all domains" },
- { "online-status", 0, POPT_ARG_NONE, 0, OPT_ONLINESTATUS, "Show whether domains are marked as online or offline"},
- { "domain-info", 'D', POPT_ARG_STRING, &string_arg, 'D', "Show most of the info we have about the domain" },
- { "user-info", 'i', POPT_ARG_STRING, &string_arg, 'i', "Get user info", "USER" },
- { "uid-info", 0, POPT_ARG_INT, &int_arg, OPT_UID_INFO, "Get user info from uid", "UID" },
- { "group-info", 0, POPT_ARG_STRING, &string_arg, OPT_GROUP_INFO, "Get group info", "GROUP" },
- { "user-groups", 'r', POPT_ARG_STRING, &string_arg, 'r', "Get user groups", "USER" },
- { "user-domgroups", 0, POPT_ARG_STRING, &string_arg,
- OPT_USERDOMGROUPS, "Get user domain groups", "SID" },
- { "user-sids", 0, POPT_ARG_STRING, &string_arg, OPT_USERSIDS, "Get user group sids for user SID", "SID" },
- { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" },
- { "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" },
- { "getdcname", 0, POPT_ARG_STRING, &string_arg, OPT_GETDCNAME,
- "Get a DC name for a foreign domain", "domainname" },
- { "dsgetdcname", 0, POPT_ARG_STRING, &string_arg, OPT_DSGETDCNAME, "Find a DC for a domain", "domainname" },
- { "get-auth-user", 0, POPT_ARG_NONE, NULL, OPT_GET_AUTH_USER, "Retrieve user and password used by winbindd (root only)", NULL },
- { "ping", 'p', POPT_ARG_NONE, 0, 'p', "Ping winbindd to see if it is alive" },
- { "domain", 0, POPT_ARG_STRING, &opt_domain_name, OPT_DOMAIN_NAME, "Define to the domain to restrict operation", "domain" },
-#ifdef WITH_FAKE_KASERVER
- { "klog", 'k', POPT_ARG_STRING, &string_arg, 'k', "set an AFS token from winbind", "user%password" },
-#endif
-#ifdef HAVE_KRB5
- { "krb5auth", 'K', POPT_ARG_STRING, &string_arg, 'K', "authenticate user using Kerberos", "user%password" },
- /* destroys wbinfo --help output */
- /* "user%password,DOM\\user%password,user@EXAMPLE.COM,EXAMPLE.COM\\user%password" }, */
-#endif
- { "separator", 0, POPT_ARG_NONE, 0, OPT_SEPARATOR, "Get the active winbind separator", NULL },
- { "verbose", 0, POPT_ARG_NONE, 0, OPT_VERBOSE, "Print additional information per command", NULL },
- { "change-user-password", 0, POPT_ARG_STRING, &string_arg, OPT_CHANGE_USER_PASSWORD, "Change the password for a user", NULL },
- POPT_COMMON_CONFIGFILE
- POPT_COMMON_VERSION
- POPT_TABLEEND
- };
-
- /* Samba client initialisation */
- load_case_tables();
-
-
- /* Parse options */
-
- pc = poptGetContext("wbinfo", argc, (const char **)argv, long_options, 0);
-
- /* Parse command line options */
-
- if (argc == 1) {
- poptPrintHelp(pc, stderr, 0);
- return 1;
- }
-
- while((opt = poptGetNextOpt(pc)) != -1) {
- /* get the generic configuration parameters like --domain */
- switch (opt) {
- case OPT_VERBOSE:
- verbose = True;
- break;
- }
- }
-
- poptFreeContext(pc);
-
- if (!lp_load(get_dyn_CONFIGFILE(), true, false, false, true)) {
- d_fprintf(stderr, "wbinfo: error opening config file %s. Error was %s\n",
- get_dyn_CONFIGFILE(), strerror(errno));
- exit(1);
- }
-
- if (!init_names())
- return 1;
-
- load_interfaces();
-
- pc = poptGetContext(NULL, argc, (const char **)argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
-
- while((opt = poptGetNextOpt(pc)) != -1) {
- switch (opt) {
- case 'u':
- if (!print_domain_users(opt_domain_name)) {
- d_fprintf(stderr, "Error looking up domain users\n");
- goto done;
- }
- break;
- case 'g':
- if (!print_domain_groups(opt_domain_name)) {
- d_fprintf(stderr, "Error looking up domain groups\n");
- goto done;
- }
- break;
- case 's':
- if (!wbinfo_lookupsid(string_arg)) {
- d_fprintf(stderr, "Could not lookup sid %s\n", string_arg);
- goto done;
- }
- break;
- case OPT_SID_TO_FULLNAME:
- if (!wbinfo_lookupsid_fullname(string_arg)) {
- d_fprintf(stderr, "Could not lookup sid %s\n",
- string_arg);
- goto done;
- }
- break;
- case 'R':
- if (!wbinfo_lookuprids(opt_domain_name, string_arg)) {
- d_fprintf(stderr, "Could not lookup RIDs %s\n", string_arg);
- goto done;
- }
- break;
- case 'n':
- if (!wbinfo_lookupname(string_arg)) {
- d_fprintf(stderr, "Could not lookup name %s\n", string_arg);
- goto done;
- }
- break;
- case 'N':
- if (!wbinfo_wins_byname(string_arg)) {
- d_fprintf(stderr, "Could not lookup WINS by name %s\n", string_arg);
- goto done;
- }
- break;
- case 'I':
- if (!wbinfo_wins_byip(string_arg)) {
- d_fprintf(stderr, "Could not lookup WINS by IP %s\n", string_arg);
- goto done;
- }
- break;
- case 'U':
- if (!wbinfo_uid_to_sid(int_arg)) {
- d_fprintf(stderr, "Could not convert uid %d to sid\n", int_arg);
- goto done;
- }
- break;
- case 'G':
- if (!wbinfo_gid_to_sid(int_arg)) {
- d_fprintf(stderr, "Could not convert gid %d to sid\n",
- int_arg);
- goto done;
- }
- break;
- case 'S':
- if (!wbinfo_sid_to_uid(string_arg)) {
- d_fprintf(stderr, "Could not convert sid %s to uid\n",
- string_arg);
- goto done;
- }
- break;
- case 'Y':
- if (!wbinfo_sid_to_gid(string_arg)) {
- d_fprintf(stderr, "Could not convert sid %s to gid\n",
- string_arg);
- goto done;
- }
- break;
- case OPT_ALLOCATE_UID:
- if (!wbinfo_allocate_uid()) {
- d_fprintf(stderr, "Could not allocate a uid\n");
- goto done;
- }
- break;
- case OPT_ALLOCATE_GID:
- if (!wbinfo_allocate_gid()) {
- d_fprintf(stderr, "Could not allocate a gid\n");
- goto done;
- }
- break;
- case OPT_SET_UID_MAPPING:
- if (!parse_mapping_arg(string_arg, &int_subarg,
- &string_subarg) ||
- !wbinfo_set_uid_mapping(int_subarg, string_subarg))
- {
- d_fprintf(stderr, "Could not create or modify "
- "uid to sid mapping\n");
- goto done;
- }
- break;
- case OPT_SET_GID_MAPPING:
- if (!parse_mapping_arg(string_arg, &int_subarg,
- &string_subarg) ||
- !wbinfo_set_gid_mapping(int_subarg, string_subarg))
- {
- d_fprintf(stderr, "Could not create or modify "
- "gid to sid mapping\n");
- goto done;
- }
- break;
- case OPT_REMOVE_UID_MAPPING:
- if (!parse_mapping_arg(string_arg, &int_subarg,
- &string_subarg) ||
- !wbinfo_remove_uid_mapping(int_subarg,
- string_subarg))
- {
- d_fprintf(stderr, "Could not remove uid to sid "
- "mapping\n");
- goto done;
- }
- break;
- case OPT_REMOVE_GID_MAPPING:
- if (!parse_mapping_arg(string_arg, &int_subarg,
- &string_subarg) ||
- !wbinfo_remove_gid_mapping(int_subarg,
- string_subarg))
- {
- d_fprintf(stderr, "Could not remove gid to sid "
- "mapping\n");
- goto done;
- }
- break;
- case 't':
- if (!wbinfo_check_secret()) {
- d_fprintf(stderr, "Could not check secret\n");
- goto done;
- }
- break;
- case 'm':
- if (!wbinfo_list_domains(false, verbose)) {
- d_fprintf(stderr, "Could not list trusted domains\n");
- goto done;
- }
- break;
- case OPT_SEQUENCE:
- if (!wbinfo_show_sequence(opt_domain_name)) {
- d_fprintf(stderr, "Could not show sequence numbers\n");
- goto done;
- }
- break;
- case OPT_ONLINESTATUS:
- if (!wbinfo_show_onlinestatus(opt_domain_name)) {
- d_fprintf(stderr, "Could not show online-status\n");
- goto done;
- }
- break;
- case 'D':
- if (!wbinfo_domain_info(string_arg)) {
- d_fprintf(stderr, "Could not get domain info\n");
- goto done;
- }
- break;
- case 'i':
- if (!wbinfo_get_userinfo(string_arg)) {
- d_fprintf(stderr, "Could not get info for user %s\n",
- string_arg);
- goto done;
- }
- break;
- case OPT_UID_INFO:
- if ( !wbinfo_get_uidinfo(int_arg)) {
- d_fprintf(stderr, "Could not get info for uid "
- "%d\n", int_arg);
- goto done;
- }
- break;
- case OPT_GROUP_INFO:
- if ( !wbinfo_get_groupinfo(string_arg)) {
- d_fprintf(stderr, "Could not get info for "
- "group %s\n", string_arg);
- goto done;
- }
- break;
- case 'r':
- if (!wbinfo_get_usergroups(string_arg)) {
- d_fprintf(stderr, "Could not get groups for user %s\n",
- string_arg);
- goto done;
- }
- break;
- case OPT_USERSIDS:
- if (!wbinfo_get_usersids(string_arg)) {
- d_fprintf(stderr, "Could not get group SIDs for user SID %s\n",
- string_arg);
- goto done;
- }
- break;
- case OPT_USERDOMGROUPS:
- if (!wbinfo_get_userdomgroups(string_arg)) {
- d_fprintf(stderr, "Could not get user's domain groups "
- "for user SID %s\n", string_arg);
- goto done;
- }
- break;
- case 'a': {
- bool got_error = false;
-
- if (!wbinfo_auth(string_arg)) {
- d_fprintf(stderr, "Could not authenticate user %s with "
- "plaintext password\n", string_arg);
- got_error = true;
- }
-
- if (!wbinfo_auth_crap(string_arg)) {
- d_fprintf(stderr, "Could not authenticate user %s with "
- "challenge/response\n", string_arg);
- got_error = true;
- }
-
- if (got_error)
- goto done;
- break;
- }
- case 'K': {
- uint32 flags = WBFLAG_PAM_KRB5 |
- WBFLAG_PAM_CACHED_LOGIN |
- WBFLAG_PAM_FALLBACK_AFTER_KRB5 |
- WBFLAG_PAM_INFO3_TEXT;
-
- if (!wbinfo_auth_krb5(string_arg, "FILE", flags)) {
- d_fprintf(stderr, "Could not authenticate user [%s] with "
- "Kerberos (ccache: %s)\n", string_arg, "FILE");
- goto done;
- }
- break;
- }
- case 'k':
- if (!wbinfo_klog(string_arg)) {
- d_fprintf(stderr, "Could not klog user\n");
- goto done;
- }
- break;
- case 'p':
- if (!wbinfo_ping()) {
- d_fprintf(stderr, "could not ping winbindd!\n");
- goto done;
- }
- break;
- case OPT_SET_AUTH_USER:
- if (!wbinfo_set_auth_user(string_arg)) {
- goto done;
- }
- break;
- case OPT_GET_AUTH_USER:
- wbinfo_get_auth_user();
- break;
- case OPT_GETDCNAME:
- if (!wbinfo_getdcname(string_arg)) {
- goto done;
- }
- break;
- case OPT_DSGETDCNAME:
- if (!wbinfo_dsgetdcname(string_arg, 0)) {
- goto done;
- }
- break;
- case OPT_SEPARATOR: {
- const char sep = winbind_separator_int(true);
- if ( !sep ) {
- goto done;
- }
- d_printf("%c\n", sep);
- break;
- }
- case OPT_LIST_ALL_DOMAINS:
- if (!wbinfo_list_domains(true, verbose)) {
- goto done;
- }
- break;
- case OPT_LIST_OWN_DOMAIN:
- if (!wbinfo_list_own_domain()) {
- goto done;
- }
- break;
- case OPT_CHANGE_USER_PASSWORD:
- if (!wbinfo_change_user_password(string_arg)) {
- d_fprintf(stderr, "Could not change user password "
- "for user %s\n", string_arg);
- goto done;
- }
- break;
-
- /* generic configuration options */
- case OPT_DOMAIN_NAME:
- break;
- case OPT_VERBOSE:
- break;
- default:
- d_fprintf(stderr, "Invalid option\n");
- poptPrintHelp(pc, stderr, 0);
- goto done;
- }
- }
-
- result = 0;
-
- /* Exit code */
-
- done:
- talloc_destroy(frame);
-
- poptFreeContext(pc);
- return result;
-}
diff --git a/source3/nsswitch/winbind_client.h b/source3/nsswitch/winbind_client.h
deleted file mode 100644
index 757f5869e9..0000000000
--- a/source3/nsswitch/winbind_client.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#include "winbind_nss_config.h"
-#include "winbind_struct_protocol.h"
-
-void winbindd_init_request(struct winbindd_request *req,int rq_type);
-void winbindd_free_response(struct winbindd_response *response);
-NSS_STATUS winbindd_send_request(int req_type, int need_priv,
- struct winbindd_request *request);
-NSS_STATUS winbindd_get_response(struct winbindd_response *response);
-NSS_STATUS winbindd_request_response(int req_type,
- struct winbindd_request *request,
- struct winbindd_response *response);
-NSS_STATUS winbindd_priv_request_response(int req_type,
- struct winbindd_request *request,
- struct winbindd_response *response);
-int winbindd_read_reply(struct winbindd_response *response);
-
-#define winbind_env_set() \
- (strcmp(getenv(WINBINDD_DONT_ENV)?getenv(WINBINDD_DONT_ENV):"0","1") == 0)
-
-#define winbind_off() \
- (setenv(WINBINDD_DONT_ENV, "1", 1) == 0)
-
-#define winbind_on() \
- (setenv(WINBINDD_DONT_ENV, "0", 1) == 0)
-
-int winbind_write_sock(void *buffer, int count, int recursing, int need_priv);
-int winbind_read_sock(void *buffer, int count);
-void winbind_close_sock(void);
-
-const char *nss_err_str(NSS_STATUS ret);
diff --git a/source3/nsswitch/winbind_krb5_locator.c b/source3/nsswitch/winbind_krb5_locator.c
deleted file mode 100644
index b9e35bdec5..0000000000
--- a/source3/nsswitch/winbind_krb5_locator.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- kerberos locator plugin
- Copyright (C) Guenther Deschner 2007-2008
-
- 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 "nsswitch/winbind_client.h"
-#include "libwbclient/wbclient.h"
-
-#ifndef DEBUG_KRB5
-#undef DEBUG_KRB5
-#endif
-
-#if defined(HAVE_KRB5) && defined(HAVE_KRB5_LOCATE_PLUGIN_H)
-
-#include <krb5/locate_plugin.h>
-
-#ifndef KRB5_PLUGIN_NO_HANDLE
-#define KRB5_PLUGIN_NO_HANDLE KRB5_KDC_UNREACH /* Heimdal */
-#endif
-
-static const char *get_service_from_locate_service_type(enum locate_service_type svc)
-{
- switch (svc) {
- case locate_service_kdc:
- case locate_service_master_kdc:
- return "88";
- case locate_service_kadmin:
- case locate_service_krb524:
- /* not supported */
- return NULL;
- case locate_service_kpasswd:
- return "464";
- default:
- break;
- }
- return NULL;
-
-}
-
-#ifdef DEBUG_KRB5
-static const char *locate_service_type_name(enum locate_service_type svc)
-{
- switch (svc) {
- case locate_service_kdc:
- return "locate_service_kdc";
- case locate_service_master_kdc:
- return "locate_service_master_kdc";
- case locate_service_kadmin:
- return "locate_service_kadmin";
- case locate_service_krb524:
- return "locate_service_krb524";
- case locate_service_kpasswd:
- return "locate_service_kpasswd";
- default:
- break;
- }
- return NULL;
-}
-
-static const char *socktype_name(int socktype)
-{
- switch (socktype) {
- case SOCK_STREAM:
- return "SOCK_STREAM";
- case SOCK_DGRAM:
- return "SOCK_DGRAM";
- default:
- break;
- }
- return "unknown";
-}
-
-static const char *family_name(int family)
-{
- switch (family) {
- case AF_UNSPEC:
- return "AF_UNSPEC";
- case AF_INET:
- return "AF_INET";
-#if defined(HAVE_IPV6)
- case AF_INET6:
- return "AF_INET6";
-#endif
- default:
- break;
- }
- return "unknown";
-}
-#endif
-
-/**
- * Check input parameters, return KRB5_PLUGIN_NO_HANDLE for unsupported ones
- *
- * @param svc
- * @param realm string
- * @param socktype integer
- * @param family integer
- *
- * @return integer.
- */
-
-static int smb_krb5_locator_lookup_sanity_check(enum locate_service_type svc,
- const char *realm,
- int socktype,
- int family)
-{
- if (!realm || strlen(realm) == 0) {
- return EINVAL;
- }
-
- switch (svc) {
- case locate_service_kdc:
- case locate_service_master_kdc:
- case locate_service_kpasswd:
- break;
- case locate_service_kadmin:
- case locate_service_krb524:
- return KRB5_PLUGIN_NO_HANDLE;
- default:
- return EINVAL;
- }
-
- switch (family) {
- case AF_UNSPEC:
- case AF_INET:
- break;
-#if defined(HAVE_IPV6)
- case AF_INET6:
- break;
-#endif
- default:
- return EINVAL;
- }
-
- switch (socktype) {
- case SOCK_STREAM:
- case SOCK_DGRAM:
- case 0: /* Heimdal uses that */
- break;
- default:
- return EINVAL;
- }
-
- return 0;
-}
-
-/**
- * Try to get addrinfo for a given host and call the krb5 callback
- *
- * @param name string
- * @param service string
- * @param in struct addrinfo hint
- * @param cbfunc krb5 callback function
- * @param cbdata void pointer cbdata
- *
- * @return krb5_error_code.
- */
-
-static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name,
- const char *service,
- struct addrinfo *in,
- int (*cbfunc)(void *, int, struct sockaddr *),
- void *cbdata)
-{
- struct addrinfo *out = NULL;
- int ret;
- int count = 3;
-
- while (count) {
-
- ret = getaddrinfo(name, service, in, &out);
- if (ret == 0) {
- break;
- }
-
- if (ret == EAI_AGAIN) {
- count--;
- continue;
- }
-
-#ifdef DEBUG_KRB5
- fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: "
- "getaddrinfo failed: %s (%d)\n",
- (unsigned int)getpid(), gai_strerror(ret), ret);
-#endif
-
- return KRB5_PLUGIN_NO_HANDLE;
- }
-
- ret = cbfunc(cbdata, out->ai_socktype, out->ai_addr);
-#ifdef DEBUG_KRB5
- if (ret) {
- fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: "
- "failed to call callback: %s (%d)\n",
- (unsigned int)getpid(), error_message(ret), ret);
- }
-#endif
-
- freeaddrinfo(out);
- return ret;
-}
-
-/**
- * PUBLIC INTERFACE: locate init
- *
- * @param context krb5_context
- * @param privata_data pointer to private data pointer
- *
- * @return krb5_error_code.
- */
-
-static krb5_error_code smb_krb5_locator_init(krb5_context context,
- void **private_data)
-{
- return 0;
-}
-
-/**
- * PUBLIC INTERFACE: close locate
- *
- * @param private_data pointer to private data
- *
- * @return void.
- */
-
-static void smb_krb5_locator_close(void *private_data)
-{
- return;
-}
-
-
-static bool ask_winbind(const char *realm, char **dcname)
-{
- wbcErr wbc_status;
- const char *dc = NULL;
- struct wbcDomainControllerInfoEx *dc_info = NULL;
- uint32_t flags;
-
- flags = WBC_LOOKUP_DC_KDC_REQUIRED |
- WBC_LOOKUP_DC_IS_DNS_NAME |
- WBC_LOOKUP_DC_RETURN_DNS_NAME |
- WBC_LOOKUP_DC_IP_REQUIRED;
-
- wbc_status = wbcLookupDomainControllerEx(realm, NULL, NULL, flags, &dc_info);
-
- if (!WBC_ERROR_IS_OK(wbc_status)) {
-#ifdef DEBUG_KRB5
- fprintf(stderr,"[%5u]: smb_krb5_locator_lookup: failed with: %s\n",
- (unsigned int)getpid(), wbcErrorString(wbc_status));
-#endif
- return false;
- }
-
- if (dc_info->dc_address) {
- dc = dc_info->dc_address;
- if (dc[0] == '\\') dc++;
- if (dc[0] == '\\') dc++;
- }
-
- if (!dc && dc_info->dc_unc) {
- dc = dc_info->dc_unc;
- if (dc[0] == '\\') dc++;
- if (dc[0] == '\\') dc++;
- }
-
- if (!dc) {
- wbcFreeMemory(dc_info);
- return false;
- }
-
- *dcname = strdup(dc);
- if (!*dcname) {
- wbcFreeMemory(dc_info);
- return false;
- }
-
- wbcFreeMemory(dc_info);
- return true;
-}
-
-/**
- * PUBLIC INTERFACE: locate lookup
- *
- * @param private_data pointer to private data
- * @param svc enum locate_service_type.
- * @param realm string
- * @param socktype integer
- * @param family integer
- * @param cbfunc callback function to send back entries
- * @param cbdata void pointer to cbdata
- *
- * @return krb5_error_code.
- */
-
-static krb5_error_code smb_krb5_locator_lookup(void *private_data,
- enum locate_service_type svc,
- const char *realm,
- int socktype,
- int family,
- int (*cbfunc)(void *, int, struct sockaddr *),
- void *cbdata)
-{
- krb5_error_code ret;
- struct addrinfo aihints;
- char *kdc_name = NULL;
- const char *service = get_service_from_locate_service_type(svc);
-
- ZERO_STRUCT(aihints);
-
-#ifdef DEBUG_KRB5
- fprintf(stderr,"[%5u]: smb_krb5_locator_lookup: called for '%s' "
- "svc: '%s' (%d) "
- "socktype: '%s' (%d), family: '%s' (%d)\n",
- (unsigned int)getpid(), realm,
- locate_service_type_name(svc), svc,
- socktype_name(socktype), socktype,
- family_name(family), family);
-#endif
- ret = smb_krb5_locator_lookup_sanity_check(svc, realm, socktype,
- family);
- if (ret) {
-#ifdef DEBUG_KRB5
- fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: "
- "returning ret: %s (%d)\n",
- (unsigned int)getpid(), error_message(ret), ret);
-#endif
- return ret;
- }
-
- if (!winbind_env_set()) {
- if (!ask_winbind(realm, &kdc_name)) {
-#ifdef DEBUG_KRB5
- fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: "
- "failed to query winbindd\n",
- (unsigned int)getpid());
-#endif
- goto failed;
- }
- } else {
- const char *env = NULL;
- char *var = NULL;
- if (asprintf(&var, "%s_%s",
- WINBINDD_LOCATOR_KDC_ADDRESS, realm) == -1) {
- goto failed;
- }
- env = getenv(var);
- if (!env) {
-#ifdef DEBUG_KRB5
- fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: "
- "failed to get kdc from env %s\n",
- (unsigned int)getpid(), var);
-#endif
- free(var);
- goto failed;
- }
- free(var);
-
- kdc_name = strdup(env);
- if (!kdc_name) {
- goto failed;
- }
- }
-#ifdef DEBUG_KRB5
- fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: "
- "got '%s' for '%s' from winbindd\n", (unsigned int)getpid(),
- kdc_name, realm);
-#endif
-
- aihints.ai_family = family;
- aihints.ai_socktype = socktype;
-
- ret = smb_krb5_locator_call_cbfunc(kdc_name,
- service,
- &aihints,
- cbfunc, cbdata);
- SAFE_FREE(kdc_name);
-
- return ret;
-
- failed:
- return KRB5_PLUGIN_NO_HANDLE;
-}
-
-#ifdef HEIMDAL_KRB5_LOCATE_PLUGIN_H
-#define SMB_KRB5_LOCATOR_SYMBOL_NAME resolve /* Heimdal */
-#else
-#define SMB_KRB5_LOCATOR_SYMBOL_NAME service_locator /* MIT */
-#endif
-
-const krb5plugin_service_locate_ftable SMB_KRB5_LOCATOR_SYMBOL_NAME = {
- 0, /* version */
- smb_krb5_locator_init,
- smb_krb5_locator_close,
- smb_krb5_locator_lookup,
-};
-
-#endif
diff --git a/source3/nsswitch/winbind_nss.h b/source3/nsswitch/winbind_nss.h
deleted file mode 100644
index 0a3bc7cefa..0000000000
--- a/source3/nsswitch/winbind_nss.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- A common place to work out how to define NSS_STATUS on various
- platforms.
-
- Copyright (C) Tim Potter 2000
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _NSSWITCH_NSS_H
-#define _NSSWITCH_NSS_H
-
-#ifdef HAVE_NSS_COMMON_H
-
-/*
- * Sun Solaris
- */
-
-#include "nsswitch/winbind_nss_solaris.h"
-
-#elif HAVE_NSS_H
-
-/*
- * Linux (glibc)
- */
-
-#include "nsswitch/winbind_nss_linux.h"
-
-#elif HAVE_NS_API_H
-
-/*
- * SGI IRIX
- */
-
-#include "nsswitch/winbind_nss_irix.h"
-
-#elif defined(HPUX) && defined(HAVE_NSSWITCH_H)
-
-/* HP-UX 11 */
-
-#include "nsswitch/winbind_nss_hpux.h"
-
-#elif defined(__NetBSD__) && defined(HAVE_GETPWENT_R)
-
-/*
- * NetBSD 3 and newer
- */
-
-#include "nsswitch/winbind_nss_netbsd.h"
-
-#else /* Nothing's defined. Neither gnu nor netbsd nor sun nor hp */
-
-typedef enum
-{
- NSS_STATUS_SUCCESS=0,
- NSS_STATUS_NOTFOUND=1,
- NSS_STATUS_UNAVAIL=2,
- NSS_STATUS_TRYAGAIN=3
-} NSS_STATUS;
-
-#endif
-
-#endif /* _NSSWITCH_NSS_H */
diff --git a/source3/nsswitch/winbind_nss_aix.c b/source3/nsswitch/winbind_nss_aix.c
deleted file mode 100644
index 9c84e5f8aa..0000000000
--- a/source3/nsswitch/winbind_nss_aix.c
+++ /dev/null
@@ -1,1077 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- AIX loadable authentication module, providing identification and
- authentication routines against Samba winbind/Windows NT Domain
-
- Copyright (C) Tim Potter 2003
- Copyright (C) Steve Roylance 2003
- Copyright (C) Andrew Tridgell 2003-2004
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
-
- To install this module copy nsswitch/WINBIND to /usr/lib/security and add
- "WINBIND" in /usr/lib/security/methods.cfg and /etc/security/user
-
- Note that this module also provides authentication and password
- changing routines, so you do not need to install the winbind PAM
- module.
-
- see
- http://publib16.boulder.ibm.com/doc_link/en_US/a_doc_lib/aixprggd/kernextc/sec_load_mod.htm
- for some information in the interface that this module implements
-
- Many thanks to Julianne Haugh for explaining some of the finer
- details of this interface.
-
- To debug this module use uess_test.c (which you can get from tridge)
- or set "options=debug" in /usr/lib/security/methods.cfg
-
-*/
-
-#include "winbind_client.h"
-#include <usersec.h>
-
-/* enable this to log which entry points have not been
- completed yet */
-#define LOG_UNIMPLEMENTED_CALLS 0
-
-
-#define WB_AIX_ENCODED '_'
-
-static int debug_enabled;
-
-
-static void logit(const char *format, ...)
-{
- va_list ap;
- FILE *f;
- if (!debug_enabled) {
- return;
- }
- f = fopen("/tmp/WINBIND_DEBUG.log", "a");
- if (!f) return;
- va_start(ap, format);
- vfprintf(f, format, ap);
- va_end(ap);
- fclose(f);
-}
-
-
-#define HANDLE_ERRORS(ret) do { \
- if ((ret) == NSS_STATUS_NOTFOUND) { \
- errno = ENOENT; \
- return NULL; \
- } else if ((ret) != NSS_STATUS_SUCCESS) { \
- errno = EIO; \
- return NULL; \
- } \
-} while (0)
-
-#define STRCPY_RET(dest, src) \
-do { \
- if (strlen(src)+1 > sizeof(dest)) { errno = EINVAL; return -1; } \
- strcpy(dest, src); \
-} while (0)
-
-#define STRCPY_RETNULL(dest, src) \
-do { \
- if (strlen(src)+1 > sizeof(dest)) { errno = EINVAL; return NULL; } \
- strcpy(dest, src); \
-} while (0)
-
-
-/* free a passwd structure */
-static void free_pwd(struct passwd *pwd)
-{
- free(pwd->pw_name);
- free(pwd->pw_passwd);
- free(pwd->pw_gecos);
- free(pwd->pw_dir);
- free(pwd->pw_shell);
- free(pwd);
-}
-
-/* free a group structure */
-static void free_grp(struct group *grp)
-{
- int i;
-
- free(grp->gr_name);
- free(grp->gr_passwd);
-
- if (!grp->gr_mem) {
- free(grp);
- return;
- }
-
- for (i=0; grp->gr_mem[i]; i++) {
- free(grp->gr_mem[i]);
- }
-
- free(grp->gr_mem);
- free(grp);
-}
-
-
-/* replace commas with nulls, and null terminate */
-static void replace_commas(char *s)
-{
- char *p, *p0=s;
- for (p=strchr(s, ','); p; p = strchr(p+1, ',')) {
- *p=0;
- p0 = p+1;
- }
-
- p0[strlen(p0)+1] = 0;
-}
-
-
-/* the decode_*() routines are used to cope with the fact that AIX 5.2
- and below cannot handle user or group names longer than 8
- characters in some interfaces. We use the normalize method to
- provide a mapping to a username that fits, by using the form '_UID'
- or '_GID'.
-
- this only works if you can guarantee that the WB_AIX_ENCODED char
- is not used as the first char of any other username
-*/
-static unsigned decode_id(const char *name)
-{
- unsigned id;
- sscanf(name+1, "%u", &id);
- return id;
-}
-
-static struct passwd *wb_aix_getpwuid(uid_t uid);
-
-static char *decode_user(const char *name)
-{
- struct passwd *pwd;
- unsigned id;
- char *ret;
-
- sscanf(name+1, "%u", &id);
- pwd = wb_aix_getpwuid(id);
- if (!pwd) {
- return NULL;
- }
- ret = strdup(pwd->pw_name);
-
- free_pwd(pwd);
-
- logit("decoded '%s' -> '%s'\n", name, ret);
-
- return ret;
-}
-
-
-/*
- fill a struct passwd from a winbindd_pw struct, allocating as a single block
-*/
-static struct passwd *fill_pwent(struct winbindd_pw *pw)
-{
- struct passwd *result;
-
- result = calloc(1, sizeof(struct passwd));
- if (!result) {
- errno = ENOMEM;
- return NULL;
- }
-
- result->pw_uid = pw->pw_uid;
- result->pw_gid = pw->pw_gid;
- result->pw_name = strdup(pw->pw_name);
- result->pw_passwd = strdup(pw->pw_passwd);
- result->pw_gecos = strdup(pw->pw_gecos);
- result->pw_dir = strdup(pw->pw_dir);
- result->pw_shell = strdup(pw->pw_shell);
-
- return result;
-}
-
-
-/*
- fill a struct group from a winbindd_pw struct, allocating as a single block
-*/
-static struct group *fill_grent(struct winbindd_gr *gr, char *gr_mem)
-{
- int i;
- struct group *result;
- char *p, *name;
-
- result = calloc(1, sizeof(struct group));
- if (!result) {
- errno = ENOMEM;
- return NULL;
- }
-
- result->gr_gid = gr->gr_gid;
-
- result->gr_name = strdup(gr->gr_name);
- result->gr_passwd = strdup(gr->gr_passwd);
-
- /* Group membership */
- if ((gr->num_gr_mem < 0) || !gr_mem) {
- gr->num_gr_mem = 0;
- }
-
- if (gr->num_gr_mem == 0) {
- /* Group is empty */
- return result;
- }
-
- result->gr_mem = (char **)malloc(sizeof(char *) * (gr->num_gr_mem+1));
- if (!result->gr_mem) {
- errno = ENOMEM;
- return NULL;
- }
-
- /* Start looking at extra data */
- i=0;
- for (name = strtok_r(gr_mem, ",", &p);
- name;
- name = strtok_r(NULL, ",", &p)) {
- if (i == gr->num_gr_mem) {
- break;
- }
- result->gr_mem[i] = strdup(name);
- i++;
- }
-
- /* Terminate list */
- result->gr_mem[i] = NULL;
-
- return result;
-}
-
-
-
-/* take a group id and return a filled struct group */
-static struct group *wb_aix_getgrgid(gid_t gid)
-{
- struct winbindd_response response;
- struct winbindd_request request;
- struct group *grp;
- NSS_STATUS ret;
-
- logit("getgrgid %d\n", gid);
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- request.data.gid = gid;
-
- ret = winbindd_request_response(WINBINDD_GETGRGID, &request, &response);
-
- logit("getgrgid ret=%d\n", ret);
-
- HANDLE_ERRORS(ret);
-
- grp = fill_grent(&response.data.gr, response.extra_data.data);
-
- winbindd_free_response(&response);
-
- return grp;
-}
-
-/* take a group name and return a filled struct group */
-static struct group *wb_aix_getgrnam(const char *name)
-{
- struct winbindd_response response;
- struct winbindd_request request;
- NSS_STATUS ret;
- struct group *grp;
-
- if (*name == WB_AIX_ENCODED) {
- return wb_aix_getgrgid(decode_id(name));
- }
-
- logit("getgrnam '%s'\n", name);
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- STRCPY_RETNULL(request.data.groupname, name);
-
- ret = winbindd_request_response(WINBINDD_GETGRNAM, &request, &response);
-
- HANDLE_ERRORS(ret);
-
- grp = fill_grent(&response.data.gr, response.extra_data.data);
-
- winbindd_free_response(&response);
-
- return grp;
-}
-
-
-/* this call doesn't have to fill in the gr_mem, but we do anyway
- for simplicity */
-static struct group *wb_aix_getgracct(void *id, int type)
-{
- if (type == 1) {
- return wb_aix_getgrnam((char *)id);
- }
- if (type == 0) {
- return wb_aix_getgrgid(*(int *)id);
- }
- errno = EINVAL;
- return NULL;
-}
-
-
-/* take a username and return a string containing a comma-separated
- list of group id numbers to which the user belongs */
-static char *wb_aix_getgrset(char *user)
-{
- struct winbindd_response response;
- struct winbindd_request request;
- NSS_STATUS ret;
- int i, idx;
- char *tmpbuf;
- int num_gids;
- gid_t *gid_list;
- char *r_user = user;
-
- if (*user == WB_AIX_ENCODED) {
- r_user = decode_user(r_user);
- if (!r_user) {
- errno = ENOENT;
- return NULL;
- }
- }
-
- logit("getgrset '%s'\n", r_user);
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- STRCPY_RETNULL(request.data.username, r_user);
-
- if (*user == WB_AIX_ENCODED) {
- free(r_user);
- }
-
- ret = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response);
-
- HANDLE_ERRORS(ret);
-
- num_gids = response.data.num_entries;
- gid_list = (gid_t *)response.extra_data.data;
-
- /* allocate a space large enough to contruct the string */
- tmpbuf = malloc(num_gids*12);
- if (!tmpbuf) {
- return NULL;
- }
-
- for (idx=i=0; i < num_gids-1; i++) {
- idx += sprintf(tmpbuf+idx, "%u,", gid_list[i]);
- }
- idx += sprintf(tmpbuf+idx, "%u", gid_list[i]);
-
- winbindd_free_response(&response);
-
- return tmpbuf;
-}
-
-
-/* take a uid and return a filled struct passwd */
-static struct passwd *wb_aix_getpwuid(uid_t uid)
-{
- struct winbindd_response response;
- struct winbindd_request request;
- NSS_STATUS ret;
- struct passwd *pwd;
-
- logit("getpwuid '%d'\n", uid);
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- request.data.uid = uid;
-
- ret = winbindd_request_response(WINBINDD_GETPWUID, &request, &response);
-
- HANDLE_ERRORS(ret);
-
- pwd = fill_pwent(&response.data.pw);
-
- winbindd_free_response(&response);
-
- logit("getpwuid gave ptr %p\n", pwd);
-
- return pwd;
-}
-
-
-/* take a username and return a filled struct passwd */
-static struct passwd *wb_aix_getpwnam(const char *name)
-{
- struct winbindd_response response;
- struct winbindd_request request;
- NSS_STATUS ret;
- struct passwd *pwd;
-
- if (*name == WB_AIX_ENCODED) {
- return wb_aix_getpwuid(decode_id(name));
- }
-
- logit("getpwnam '%s'\n", name);
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- STRCPY_RETNULL(request.data.username, name);
-
- ret = winbindd_request_response(WINBINDD_GETPWNAM, &request, &response);
-
- HANDLE_ERRORS(ret);
-
- pwd = fill_pwent(&response.data.pw);
-
- winbindd_free_response(&response);
-
- logit("getpwnam gave ptr %p\n", pwd);
-
- return pwd;
-}
-
-/*
- list users
-*/
-static int wb_aix_lsuser(char *attributes[], attrval_t results[], int size)
-{
- NSS_STATUS ret;
- struct winbindd_request request;
- struct winbindd_response response;
- int len;
- char *s;
-
- if (size != 1 || strcmp(attributes[0], S_USERS) != 0) {
- logit("invalid lsuser op\n");
- errno = EINVAL;
- return -1;
- }
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- ret = winbindd_request_response(WINBINDD_LIST_USERS, &request, &response);
- if (ret != 0) {
- errno = EINVAL;
- return -1;
- }
-
- len = strlen(response.extra_data.data);
-
- s = malloc(len+2);
- if (!s) {
- winbindd_free_response(&response);
- errno = ENOMEM;
- return -1;
- }
-
- memcpy(s, response.extra_data.data, len+1);
-
- replace_commas(s);
-
- results[0].attr_un.au_char = s;
- results[0].attr_flag = 0;
-
- winbindd_free_response(&response);
-
- return 0;
-}
-
-
-/*
- list groups
-*/
-static int wb_aix_lsgroup(char *attributes[], attrval_t results[], int size)
-{
- NSS_STATUS ret;
- struct winbindd_request request;
- struct winbindd_response response;
- int len;
- char *s;
-
- if (size != 1 || strcmp(attributes[0], S_GROUPS) != 0) {
- logit("invalid lsgroup op\n");
- errno = EINVAL;
- return -1;
- }
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- ret = winbindd_request_response(WINBINDD_LIST_GROUPS, &request, &response);
- if (ret != 0) {
- errno = EINVAL;
- return -1;
- }
-
- len = strlen(response.extra_data.data);
-
- s = malloc(len+2);
- if (!s) {
- winbindd_free_response(&response);
- errno = ENOMEM;
- return -1;
- }
-
- memcpy(s, response.extra_data.data, len+1);
-
- replace_commas(s);
-
- results[0].attr_un.au_char = s;
- results[0].attr_flag = 0;
-
- winbindd_free_response(&response);
-
- return 0;
-}
-
-
-static attrval_t pwd_to_group(struct passwd *pwd)
-{
- attrval_t r;
- struct group *grp = wb_aix_getgrgid(pwd->pw_gid);
-
- if (!grp) {
- r.attr_flag = EINVAL;
- } else {
- r.attr_flag = 0;
- r.attr_un.au_char = strdup(grp->gr_name);
- free_grp(grp);
- }
-
- return r;
-}
-
-static attrval_t pwd_to_groupsids(struct passwd *pwd)
-{
- attrval_t r;
- char *s, *p;
-
- if ( (s = wb_aix_getgrset(pwd->pw_name)) == NULL ) {
- r.attr_flag = EINVAL;
- return r;
- }
-
- if ( (p = malloc(strlen(s)+2)) == NULL ) {
- r.attr_flag = ENOMEM;
- return r;
- }
-
- strcpy(p, s);
- replace_commas(p);
- free(s);
-
- r.attr_un.au_char = p;
-
- return r;
-}
-
-static attrval_t pwd_to_sid(struct passwd *pwd)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- attrval_t r;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- request.data.uid = pwd->pw_uid;
-
- if (winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response) !=
- NSS_STATUS_SUCCESS) {
- r.attr_flag = ENOENT;
- } else {
- r.attr_flag = 0;
- r.attr_un.au_char = strdup(response.data.sid.sid);
- }
-
- return r;
-}
-
-static int wb_aix_user_attrib(const char *key, char *attributes[],
- attrval_t results[], int size)
-{
- struct passwd *pwd;
- int i;
-
- pwd = wb_aix_getpwnam(key);
- if (!pwd) {
- errno = ENOENT;
- return -1;
- }
-
- for (i=0;i<size;i++) {
- results[i].attr_flag = 0;
-
- if (strcmp(attributes[i], S_ID) == 0) {
- results[i].attr_un.au_int = pwd->pw_uid;
-#ifdef _AIXVERSION_530
- } else if (strcmp(attributes[i], S_PGID) == 0) {
- results[i].attr_un.au_int = pwd->pw_gid;
-#endif
- } else if (strcmp(attributes[i], S_PWD) == 0) {
- results[i].attr_un.au_char = strdup(pwd->pw_passwd);
- } else if (strcmp(attributes[i], S_HOME) == 0) {
- results[i].attr_un.au_char = strdup(pwd->pw_dir);
- } else if (strcmp(attributes[i], S_SHELL) == 0) {
- results[i].attr_un.au_char = strdup(pwd->pw_shell);
- } else if (strcmp(attributes[i], S_REGISTRY) == 0) {
- results[i].attr_un.au_char = strdup("WINBIND");
- } else if (strcmp(attributes[i], S_GECOS) == 0) {
- results[i].attr_un.au_char = strdup(pwd->pw_gecos);
- } else if (strcmp(attributes[i], S_PGRP) == 0) {
- results[i] = pwd_to_group(pwd);
- } else if (strcmp(attributes[i], S_GROUPS) == 0) {
- results[i] = pwd_to_groupsids(pwd);
- } else if (strcmp(attributes[i], "SID") == 0) {
- results[i] = pwd_to_sid(pwd);
- } else {
- logit("Unknown user attribute '%s'\n", attributes[i]);
- results[i].attr_flag = EINVAL;
- }
- }
-
- free_pwd(pwd);
-
- return 0;
-}
-
-static int wb_aix_group_attrib(const char *key, char *attributes[],
- attrval_t results[], int size)
-{
- struct group *grp;
- int i;
-
- grp = wb_aix_getgrnam(key);
- if (!grp) {
- errno = ENOENT;
- return -1;
- }
-
- for (i=0;i<size;i++) {
- results[i].attr_flag = 0;
-
- if (strcmp(attributes[i], S_PWD) == 0) {
- results[i].attr_un.au_char = strdup(grp->gr_passwd);
- } else if (strcmp(attributes[i], S_ID) == 0) {
- results[i].attr_un.au_int = grp->gr_gid;
- } else {
- logit("Unknown group attribute '%s'\n", attributes[i]);
- results[i].attr_flag = EINVAL;
- }
- }
-
- free_grp(grp);
-
- return 0;
-}
-
-
-/*
- called for user/group enumerations
-*/
-static int wb_aix_getentry(char *key, char *table, char *attributes[],
- attrval_t results[], int size)
-{
- logit("Got getentry with key='%s' table='%s' size=%d attributes[0]='%s'\n",
- key, table, size, attributes[0]);
-
- if (strcmp(key, "ALL") == 0 &&
- strcmp(table, "user") == 0) {
- return wb_aix_lsuser(attributes, results, size);
- }
-
- if (strcmp(key, "ALL") == 0 &&
- strcmp(table, "group") == 0) {
- return wb_aix_lsgroup(attributes, results, size);
- }
-
- if (strcmp(table, "user") == 0) {
- return wb_aix_user_attrib(key, attributes, results, size);
- }
-
- if (strcmp(table, "group") == 0) {
- return wb_aix_group_attrib(key, attributes, results, size);
- }
-
- logit("Unknown getentry operation key='%s' table='%s'\n", key, table);
-
- errno = ENOSYS;
- return -1;
-}
-
-
-
-/*
- called to start the backend
-*/
-static void *wb_aix_open(const char *name, const char *domain, int mode, char *options)
-{
- if (strstr(options, "debug")) {
- debug_enabled = 1;
- }
- logit("open name='%s' mode=%d domain='%s' options='%s'\n", name, domain,
- mode, options);
- return NULL;
-}
-
-static void wb_aix_close(void *token)
-{
- logit("close\n");
- return;
-}
-
-#ifdef HAVE_STRUCT_SECMETHOD_TABLE_METHOD_ATTRLIST
-/*
- return a list of additional attributes supported by the backend
-*/
-static attrlist_t **wb_aix_attrlist(void)
-{
- /* pretty confusing but we are allocating the array of pointers
- and the structures we'll be pointing to all at once. So
- you need N+1 pointers and N structures. */
-
- attrlist_t **ret = NULL;
- attrlist_t *offset = NULL;
- int i;
- int n;
- size_t size;
-
- struct attr_types {
- const char *name;
- int flags;
- int type;
- } attr_list[] = {
- /* user attributes */
- {S_ID, AL_USERATTR, SEC_INT},
- {S_PGRP, AL_USERATTR, SEC_CHAR},
- {S_HOME, AL_USERATTR, SEC_CHAR},
- {S_SHELL, AL_USERATTR, SEC_CHAR},
-#ifdef _AIXVERSION_530
- {S_PGID, AL_USERATTR, SEC_INT},
-#endif
- {S_GECOS, AL_USERATTR, SEC_CHAR},
- {S_SHELL, AL_USERATTR, SEC_CHAR},
- {S_PGRP, AL_USERATTR, SEC_CHAR},
- {S_GROUPS, AL_USERATTR, SEC_LIST},
- {"SID", AL_USERATTR, SEC_CHAR},
-
- /* group attributes */
- {S_ID, AL_GROUPATTR, SEC_INT}
- };
-
- logit("method attrlist called\n");
-
- n = sizeof(attr_list) / sizeof(struct attr_types);
- size = (n*sizeof(attrlist_t *));
-
- if ( (ret = malloc( size )) == NULL ) {
- errno = ENOMEM;
- return NULL;
- }
-
- /* offset to where the structures start in the buffer */
-
- offset = (attrlist_t *)(ret + n);
-
- /* now loop over the user_attr_list[] array and add
- all the members */
-
- for ( i=0; i<n; i++ ) {
- attrlist_t *a = malloc(sizeof(attrlist_t));
-
- if ( !a ) {
- /* this is bad. Just bail */
- return NULL;
- }
-
- a->al_name = strdup(attr_list[i].name);
- a->al_flags = attr_list[i].flags;
- a->al_type = attr_list[i].type;
-
- ret[i] = a;
- }
- ret[n] = NULL;
-
- return ret;
-}
-#endif
-
-
-/*
- turn a long username into a short one. Needed to cope with the 8 char
- username limit in AIX 5.2 and below
-*/
-static int wb_aix_normalize(char *longname, char *shortname)
-{
- struct passwd *pwd;
-
- logit("normalize '%s'\n", longname);
-
- /* automatically cope with AIX 5.3 with longer usernames
- when it comes out */
- if (S_NAMELEN > strlen(longname)) {
- strcpy(shortname, longname);
- return 1;
- }
-
- pwd = wb_aix_getpwnam(longname);
- if (!pwd) {
- errno = ENOENT;
- return 0;
- }
-
- sprintf(shortname, "%c%07u", WB_AIX_ENCODED, pwd->pw_uid);
-
- free_pwd(pwd);
-
- return 1;
-}
-
-
-/*
- authenticate a user
- */
-static int wb_aix_authenticate(char *user, char *pass,
- int *reenter, char **message)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
- char *r_user = user;
-
- logit("authenticate '%s' response='%s'\n", user, pass);
-
- *reenter = 0;
- *message = NULL;
-
- /* Send off request */
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- if (*user == WB_AIX_ENCODED) {
- r_user = decode_user(r_user);
- if (!r_user) {
- return AUTH_NOTFOUND;
- }
- }
-
- STRCPY_RET(request.data.auth.user, r_user);
- STRCPY_RET(request.data.auth.pass, pass);
-
- if (*user == WB_AIX_ENCODED) {
- free(r_user);
- }
-
- result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response);
-
- winbindd_free_response(&response);
-
- logit("auth result %d for '%s'\n", result, user);
-
- if (result == NSS_STATUS_SUCCESS) {
- errno = 0;
- return AUTH_SUCCESS;
- }
-
- return AUTH_FAILURE;
-}
-
-
-/*
- change a user password
-*/
-static int wb_aix_chpass(char *user, char *oldpass, char *newpass, char **message)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
- char *r_user = user;
-
- if (*user == WB_AIX_ENCODED) {
- r_user = decode_user(r_user);
- if (!r_user) {
- errno = ENOENT;
- return -1;
- }
- }
-
- logit("chpass '%s' old='%s' new='%s'\n", r_user, oldpass, newpass);
-
- *message = NULL;
-
- /* Send off request */
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- STRCPY_RET(request.data.chauthtok.user, r_user);
- STRCPY_RET(request.data.chauthtok.oldpass, oldpass);
- STRCPY_RET(request.data.chauthtok.newpass, newpass);
-
- if (*user == WB_AIX_ENCODED) {
- free(r_user);
- }
-
- result = winbindd_request_response(WINBINDD_PAM_CHAUTHTOK, &request, &response);
-
- winbindd_free_response(&response);
-
- if (result == NSS_STATUS_SUCCESS) {
- errno = 0;
- return 0;
- }
-
- errno = EINVAL;
- return -1;
-}
-
-/*
- don't do any password strength testing for now
-*/
-static int wb_aix_passwdrestrictions(char *user, char *newpass, char *oldpass,
- char **message)
-{
- logit("passwdresrictions called for '%s'\n", user);
- return 0;
-}
-
-
-static int wb_aix_passwdexpired(char *user, char **message)
-{
- logit("passwdexpired '%s'\n", user);
- /* we should check the account bits here */
- return 0;
-}
-
-
-/*
- we can't return a crypt() password
-*/
-static char *wb_aix_getpasswd(char *user)
-{
- logit("getpasswd '%s'\n", user);
- errno = ENOSYS;
- return NULL;
-}
-
-/*
- this is called to update things like the last login time. We don't
- currently pass this onto the DC
-*/
-static int wb_aix_putentry(char *key, char *table, char *attributes[],
- attrval_t values[], int size)
-{
- logit("putentry key='%s' table='%s' attrib='%s'\n",
- key, table, size>=1?attributes[0]:"<null>");
- errno = ENOSYS;
- return -1;
-}
-
-static int wb_aix_commit(char *key, char *table)
-{
- logit("commit key='%s' table='%s'\n");
- errno = ENOSYS;
- return -1;
-}
-
-static int wb_aix_getgrusers(char *group, void *result, int type, int *size)
-{
- logit("getgrusers group='%s'\n", group);
- errno = ENOSYS;
- return -1;
-}
-
-
-#define DECL_METHOD(x) \
-int method_ ## x(void) \
-{ \
- logit("UNIMPLEMENTED METHOD '%s'\n", #x); \
- errno = EINVAL; \
- return -1; \
-}
-
-#if LOG_UNIMPLEMENTED_CALLS
-DECL_METHOD(delgroup);
-DECL_METHOD(deluser);
-DECL_METHOD(newgroup);
-DECL_METHOD(newuser);
-DECL_METHOD(putgrent);
-DECL_METHOD(putgrusers);
-DECL_METHOD(putpwent);
-DECL_METHOD(lock);
-DECL_METHOD(unlock);
-DECL_METHOD(getcred);
-DECL_METHOD(setcred);
-DECL_METHOD(deletecred);
-#endif
-
-int wb_aix_init(struct secmethod_table *methods)
-{
- ZERO_STRUCTP(methods);
-
-#ifdef HAVE_STRUCT_SECMETHOD_TABLE_METHOD_VERSION
- methods->method_version = SECMETHOD_VERSION_520;
-#endif
-
- methods->method_getgrgid = wb_aix_getgrgid;
- methods->method_getgrnam = wb_aix_getgrnam;
- methods->method_getgrset = wb_aix_getgrset;
- methods->method_getpwnam = wb_aix_getpwnam;
- methods->method_getpwuid = wb_aix_getpwuid;
- methods->method_getentry = wb_aix_getentry;
- methods->method_open = wb_aix_open;
- methods->method_close = wb_aix_close;
- methods->method_normalize = wb_aix_normalize;
- methods->method_passwdexpired = wb_aix_passwdexpired;
- methods->method_putentry = wb_aix_putentry;
- methods->method_getpasswd = wb_aix_getpasswd;
- methods->method_authenticate = wb_aix_authenticate;
- methods->method_commit = wb_aix_commit;
- methods->method_chpass = wb_aix_chpass;
- methods->method_passwdrestrictions = wb_aix_passwdrestrictions;
- methods->method_getgracct = wb_aix_getgracct;
- methods->method_getgrusers = wb_aix_getgrusers;
-#ifdef HAVE_STRUCT_SECMETHOD_TABLE_METHOD_ATTRLIST
- methods->method_attrlist = wb_aix_attrlist;
-#endif
-
-#if LOG_UNIMPLEMENTED_CALLS
- methods->method_delgroup = method_delgroup;
- methods->method_deluser = method_deluser;
- methods->method_newgroup = method_newgroup;
- methods->method_newuser = method_newuser;
- methods->method_putgrent = method_putgrent;
- methods->method_putgrusers = method_putgrusers;
- methods->method_putpwent = method_putpwent;
- methods->method_lock = method_lock;
- methods->method_unlock = method_unlock;
- methods->method_getcred = method_getcred;
- methods->method_setcred = method_setcred;
- methods->method_deletecred = method_deletecred;
-#endif
-
- return AUTH_SUCCESS;
-}
-
diff --git a/source3/nsswitch/winbind_nss_config.h b/source3/nsswitch/winbind_nss_config.h
deleted file mode 100644
index bed507fdeb..0000000000
--- a/source3/nsswitch/winbind_nss_config.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon for ntdom nss module
-
- Copyright (C) Tim Potter 2000
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _WINBIND_NSS_CONFIG_H
-#define _WINBIND_NSS_CONFIG_H
-
-/* shutup the compiler warnings due to krb5.h on 64-bit sles9 */
-#ifdef SIZEOF_LONG
-#undef SIZEOF_LONG
-#endif
-
-/*
- * we don't need socket wrapper
- * nor nss wrapper here and we don't
- * want to depend on swrap_close()
- * so we better disable both
- */
-#define SOCKET_WRAPPER_NOT_REPLACE
-#define NSS_WRAPPER_NOT_REPLACE
-
-/* Include header files from data in config.h file */
-
-#ifndef NO_CONFIG_H
-#include "../replace/replace.h"
-#endif
-
-#include "system/filesys.h"
-#include "system/network.h"
-#include "system/passwd.h"
-
-#include "nsswitch/winbind_nss.h"
-
-/* I'm trying really hard not to include anything from smb.h with the
- result of some silly looking redeclaration of structures. */
-
-#ifndef FSTRING_LEN
-#define FSTRING_LEN 256
-typedef char fstring[FSTRING_LEN];
-#endif
-
-/* Some systems (SCO) treat UNIX domain sockets as FIFOs */
-
-#ifndef S_IFSOCK
-#define S_IFSOCK S_IFIFO
-#endif
-
-#ifndef S_ISSOCK
-#define S_ISSOCK(mode) ((mode & S_IFSOCK) == S_IFSOCK)
-#endif
-
-#endif
diff --git a/source3/nsswitch/winbind_nss_freebsd.c b/source3/nsswitch/winbind_nss_freebsd.c
deleted file mode 100644
index 02e29f3131..0000000000
--- a/source3/nsswitch/winbind_nss_freebsd.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- AIX loadable authentication module, providing identification
- routines against Samba winbind/Windows NT Domain
-
- Copyright (C) Aaron Collins 2003
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "winbind_client.h"
-
-/* Make sure that the module gets registered needed by freebsd 5.1 */
-
-extern enum nss_status _nss_winbind_getgrent_r(struct group *, char *, size_t,
- int *);
-extern enum nss_status _nss_winbind_getgrnam_r(const char *, struct group *,
- char *, size_t, int *);
-extern enum nss_status _nss_winbind_getgrgid_r(gid_t gid, struct group *, char *,
- size_t, int *);
-extern enum nss_status _nss_winbind_setgrent(void);
-extern enum nss_status _nss_winbind_endgrent(void);
-
-extern enum nss_status _nss_winbind_getpwent_r(struct passwd *, char *, size_t,
- int *);
-extern enum nss_status _nss_winbind_getpwnam_r(const char *, struct passwd *,
- char *, size_t, int *);
-extern enum nss_status _nss_winbind_getpwuid_r(gid_t gid, struct passwd *, char *,
- size_t, int *);
-extern enum nss_status _nss_winbind_setpwent(void);
-extern enum nss_status _nss_winbind_endpwent(void);
-
-NSS_METHOD_PROTOTYPE(__nss_compat_getgrnam_r);
-NSS_METHOD_PROTOTYPE(__nss_compat_getgrgid_r);
-NSS_METHOD_PROTOTYPE(__nss_compat_getgrent_r);
-NSS_METHOD_PROTOTYPE(__nss_compat_setgrent);
-NSS_METHOD_PROTOTYPE(__nss_compat_endgrent);
-
-NSS_METHOD_PROTOTYPE(__nss_compat_getpwnam_r);
-NSS_METHOD_PROTOTYPE(__nss_compat_getpwuid_r);
-NSS_METHOD_PROTOTYPE(__nss_compat_getpwent_r);
-NSS_METHOD_PROTOTYPE(__nss_compat_setpwent);
-NSS_METHOD_PROTOTYPE(__nss_compat_endpwent);
-
-static ns_mtab methods[] = {
-{ NSDB_GROUP, "getgrnam_r", __nss_compat_getgrnam_r, _nss_winbind_getgrnam_r },
-{ NSDB_GROUP, "getgrgid_r", __nss_compat_getgrgid_r, _nss_winbind_getgrgid_r },
-{ NSDB_GROUP, "getgrent_r", __nss_compat_getgrent_r, _nss_winbind_getgrent_r },
-{ NSDB_GROUP, "endgrent", __nss_compat_setgrent, _nss_winbind_setgrent },
-{ NSDB_GROUP, "setgrent", __nss_compat_endgrent, _nss_winbind_endgrent },
-
-{ NSDB_PASSWD, "getpwnam_r", __nss_compat_getpwnam_r, _nss_winbind_getpwnam_r },
-{ NSDB_PASSWD, "getpwuid_r", __nss_compat_getpwuid_r, _nss_winbind_getpwuid_r },
-{ NSDB_PASSWD, "getpwent_r", __nss_compat_getpwent_r, _nss_winbind_getpwent_r },
-{ NSDB_PASSWD, "endpwent", __nss_compat_setpwent, _nss_winbind_setpwent },
-{ NSDB_PASSWD, "setpwent", __nss_compat_endpwent, _nss_winbind_endpwent },
-
-};
-
-ns_mtab *
-nss_module_register(const char *source, unsigned int *mtabsize,
- nss_module_unregister_fn *unreg)
-{
- *mtabsize = sizeof(methods)/sizeof(methods[0]);
- *unreg = NULL;
- return (methods);
-}
diff --git a/source3/nsswitch/winbind_nss_hpux.h b/source3/nsswitch/winbind_nss_hpux.h
deleted file mode 100644
index 62cf3c26c5..0000000000
--- a/source3/nsswitch/winbind_nss_hpux.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Donated by HP to enable Winbindd to build on HPUX 11.x.
- Copyright (C) Jeremy Allison 2002.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _WINBIND_NSS_HPUX_H
-#define _WINBIND_NSS_HPUX_H
-
-#include <nsswitch.h>
-
-#define NSS_STATUS_SUCCESS NSS_SUCCESS
-#define NSS_STATUS_NOTFOUND NSS_NOTFOUND
-#define NSS_STATUS_UNAVAIL NSS_UNAVAIL
-#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN
-
-#ifdef HAVE_SYNCH_H
-#include <synch.h>
-#endif
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
-
-typedef enum {
- NSS_SUCCESS,
- NSS_NOTFOUND,
- NSS_UNAVAIL,
- NSS_TRYAGAIN
-} nss_status_t;
-
-typedef nss_status_t NSS_STATUS;
-
-struct nss_backend;
-
-typedef nss_status_t (*nss_backend_op_t)(struct nss_backend *, void *args);
-
-struct nss_backend {
- nss_backend_op_t *ops;
- int n_ops;
-};
-typedef struct nss_backend nss_backend_t;
-typedef int nss_dbop_t;
-
-#include <errno.h>
-#include <netdb.h>
-#include <limits.h>
-
-#ifndef NSS_INCLUDE_UNSAFE
-#define NSS_INCLUDE_UNSAFE 1 /* Build old, MT-unsafe interfaces, */
-#endif /* NSS_INCLUDE_UNSAFE */
-
-enum nss_netgr_argn {
- NSS_NETGR_MACHINE,
- NSS_NETGR_USER,
- NSS_NETGR_DOMAIN,
- NSS_NETGR_N
-};
-
-enum nss_netgr_status {
- NSS_NETGR_FOUND,
- NSS_NETGR_NO,
- NSS_NETGR_NOMEM
-};
-
-typedef unsigned nss_innetgr_argc;
-typedef char **nss_innetgr_argv;
-
-struct nss_innetgr_1arg {
- nss_innetgr_argc argc;
- nss_innetgr_argv argv;
-};
-
-typedef struct {
- void *result; /* "result" parameter to getXbyY_r() */
- char *buffer; /* "buffer" " " */
- int buflen; /* "buflen" " " */
-} nss_XbyY_buf_t;
-
-extern nss_XbyY_buf_t *_nss_XbyY_buf_alloc(int struct_size, int buffer_size);
-extern void _nss_XbyY_buf_free(nss_XbyY_buf_t *);
-
-union nss_XbyY_key {
- uid_t uid;
- gid_t gid;
- const char *name;
- int number;
- struct {
- long net;
- int type;
- } netaddr;
- struct {
- const char *addr;
- int len;
- int type;
- } hostaddr;
- struct {
- union {
- const char *name;
- int port;
- } serv;
- const char *proto;
- } serv;
- void *ether;
-};
-
-typedef struct nss_XbyY_args {
- nss_XbyY_buf_t buf;
- int stayopen;
- /*
- * Support for setXXXent(stayopen)
- * Used only in hosts, protocols,
- * networks, rpc, and services.
- */
- int (*str2ent)(const char *instr, int instr_len, void *ent, char *buffer, int buflen);
- union nss_XbyY_key key;
-
- void *returnval;
- int erange;
- int h_errno;
- nss_status_t status;
-} nss_XbyY_args_t;
-
-#endif /* _WINBIND_NSS_HPUX_H */
diff --git a/source3/nsswitch/winbind_nss_irix.c b/source3/nsswitch/winbind_nss_irix.c
deleted file mode 100644
index 5bc0fa54da..0000000000
--- a/source3/nsswitch/winbind_nss_irix.c
+++ /dev/null
@@ -1,633 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Windows NT Domain nsswitch module
-
- Copyright (C) Tim Potter 2000
- Copyright (C) James Peach 2006
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "winbind_client.h"
-
-#ifndef PRINTF_ATTRIBUTE
-#define PRINTF_ATTRIBUTE(m, n)
-#endif
-
-#ifndef HAVE_ASPRINTF_DECL
-/*PRINTFLIKE2 */
-int asprintf(char **,const char *, ...) PRINTF_ATTRIBUTE(2,3);
-#endif
-
-#ifdef HAVE_NS_API_H
-#undef STATIC
-#undef DYNAMIC
-#include <ns_daemon.h>
-#endif
-
-/* Maximum number of users to pass back over the unix domain socket
- per call. This is not a static limit on the total number of users
- or groups returned in total. */
-
-#define MAX_GETPWENT_USERS 250
-#define MAX_GETGRENT_USERS 250
-
-/* Prototypes from wb_common.c */
-
-extern int winbindd_fd;
-
-#ifdef HAVE_NS_API_H
-
-/* IRIX version */
-
-static int send_next_request(nsd_file_t *, struct winbindd_request *);
-static int do_list(int state, nsd_file_t *rq);
-
-static nsd_file_t *current_rq = NULL;
-static int current_winbind_xid = 0;
-static int next_winbind_xid = 0;
-
-typedef struct winbind_xid {
- int xid;
- nsd_file_t *rq;
- struct winbindd_request *request;
- struct winbind_xid *next;
-} winbind_xid_t;
-
-static winbind_xid_t *winbind_xids = (winbind_xid_t *)0;
-
-static int
-winbind_xid_new(int xid, nsd_file_t *rq, struct winbindd_request *request)
-{
- winbind_xid_t *new;
-
- nsd_logprintf(NSD_LOG_LOW,
- "entering winbind_xid_new xid = %d rq = 0x%x, request = 0x%x\n",
- xid, rq, request);
- new = (winbind_xid_t *)nsd_calloc(1,sizeof(winbind_xid_t));
- if (!new) {
- nsd_logprintf(NSD_LOG_RESOURCE,"winbind_xid_new: failed malloc\n");
- return NSD_ERROR;
- }
-
- new->xid = xid;
- new->rq = rq;
- new->request = request;
- new->next = winbind_xids;
- winbind_xids = new;
-
- return NSD_CONTINUE;
-}
-
-/*
-** This routine will look down the xid list and return the request
-** associated with an xid. We remove the record if it is found.
-*/
-nsd_file_t *
-winbind_xid_lookup(int xid, struct winbindd_request **requestp)
-{
- winbind_xid_t **last, *dx;
- nsd_file_t *result=0;
-
- for (last = &winbind_xids, dx = winbind_xids; dx && (dx->xid != xid);
- last = &dx->next, dx = dx->next);
- if (dx) {
- *last = dx->next;
- result = dx->rq;
- *requestp = dx->request;
- SAFE_FREE(dx);
- }
- nsd_logprintf(NSD_LOG_LOW,
- "entering winbind_xid_lookup xid = %d rq = 0x%x, request = 0x%x\n",
- xid, result, dx->request);
-
- return result;
-}
-
-static int
-winbind_startnext_timeout(nsd_file_t **rqp, nsd_times_t *to)
-{
- nsd_file_t *rq;
- struct winbindd_request *request;
-
- nsd_logprintf(NSD_LOG_MIN, "timeout (winbind startnext)\n");
- rq = to->t_file;
- *rqp = rq;
- nsd_timeout_remove(rq);
- request = to->t_clientdata;
- return(send_next_request(rq, request));
-}
-
-static void
-dequeue_request(void)
-{
- nsd_file_t *rq;
- struct winbindd_request *request;
-
- /*
- * Check for queued requests
- */
- if (winbind_xids) {
- nsd_logprintf(NSD_LOG_MIN, "timeout (winbind) unqueue xid %d\n",
- current_winbind_xid);
- rq = winbind_xid_lookup(current_winbind_xid++, &request);
- /* cause a timeout on the queued request so we can send it */
- nsd_timeout_new(rq,1,winbind_startnext_timeout,request);
- }
-}
-
-static int
-do_request(nsd_file_t *rq, struct winbindd_request *request)
-{
- if (winbind_xids == NULL) {
- /*
- * No outstanding requests.
- * Send off the request to winbindd
- */
- nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) sending request\n");
- return(send_next_request(rq, request));
- } else {
- /*
- * Just queue it up for now - previous callout or timout
- * will start it up
- */
- nsd_logprintf(NSD_LOG_MIN,
- "lookup (winbind): queue request xid = %d\n",
- next_winbind_xid);
- return(winbind_xid_new(next_winbind_xid++, rq, request));
- }
-}
-
-static int
-winbind_callback(nsd_file_t **rqp, int fd)
-{
- struct winbindd_response response;
- nsd_file_t *rq;
- NSS_STATUS status;
- char * result = NULL;
- size_t rlen;
-
- dequeue_request();
-
- nsd_logprintf(NSD_LOG_MIN, "entering callback (winbind)\n");
-
- rq = current_rq;
- *rqp = rq;
-
- nsd_timeout_remove(rq);
- nsd_callback_remove(fd);
-
- ZERO_STRUCT(response);
- status = winbindd_get_response(&response);
-
- if (status != NSS_STATUS_SUCCESS) {
- /* free any extra data area in response structure */
- winbindd_free_response(&response);
- nsd_logprintf(NSD_LOG_MIN,
- "callback (winbind) returning not found, status = %d\n",
- status);
-
- switch (status) {
- case NSS_STATUS_UNAVAIL:
- rq->f_status = NS_UNAVAIL;
- break;
- case NSS_STATUS_TRYAGAIN:
- rq->f_status = NS_TRYAGAIN;
- break;
- case NSS_STATUS_NOTFOUND:
- /* FALLTHRU */
- default:
- rq->f_status = NS_NOTFOUND;
- }
-
- return NSD_NEXT;
- }
-
- switch ((int)rq->f_cmd_data) {
- case WINBINDD_WINS_BYNAME:
- case WINBINDD_WINS_BYIP:
- nsd_logprintf(NSD_LOG_MIN,
- "callback (winbind) WINS_BYNAME | WINS_BYIP\n");
-
- rlen = asprintf(&result, "%s\n", response.data.winsresp);
- if (rlen == 0 || result == NULL) {
- return NSD_ERROR;
- }
-
- winbindd_free_response(&response);
-
- nsd_logprintf(NSD_LOG_MIN, " %s\n", result);
- nsd_set_result(rq, NS_SUCCESS, result, rlen, DYNAMIC);
- return NSD_OK;
-
- case WINBINDD_GETPWUID:
- case WINBINDD_GETPWNAM:
- {
- struct winbindd_pw *pw = &response.data.pw;
-
- nsd_logprintf(NSD_LOG_MIN,
- "callback (winbind) GETPWUID | GETPWUID\n");
-
- rlen = asprintf(&result,"%s:%s:%d:%d:%s:%s:%s\n",
- pw->pw_name,
- pw->pw_passwd,
- pw->pw_uid,
- pw->pw_gid,
- pw->pw_gecos,
- pw->pw_dir,
- pw->pw_shell);
- if (rlen == 0 || result == NULL)
- return NSD_ERROR;
-
- winbindd_free_response(&response);
-
- nsd_logprintf(NSD_LOG_MIN, " %s\n", result);
- nsd_set_result(rq, NS_SUCCESS, result, rlen, DYNAMIC);
- return NSD_OK;
- }
-
- case WINBINDD_GETGRNAM:
- case WINBINDD_GETGRGID:
- {
- const struct winbindd_gr *gr = &response.data.gr;
- const char * members;
-
- nsd_logprintf(NSD_LOG_MIN,
- "callback (winbind) GETGRNAM | GETGRGID\n");
-
- if (gr->num_gr_mem && response.extra_data.data) {
- members = response.extra_data.data;
- } else {
- members = "";
- }
-
- rlen = asprintf(&result, "%s:%s:%d:%s\n",
- gr->gr_name, gr->gr_passwd, gr->gr_gid, members);
- if (rlen == 0 || result == NULL)
- return NSD_ERROR;
-
- winbindd_free_response(&response);
-
- nsd_logprintf(NSD_LOG_MIN, " %s\n", result);
- nsd_set_result(rq, NS_SUCCESS, result, rlen, DYNAMIC);
- return NSD_OK;
- }
-
- case WINBINDD_SETGRENT:
- case WINBINDD_SETPWENT:
- nsd_logprintf(NSD_LOG_MIN,
- "callback (winbind) SETGRENT | SETPWENT\n");
- winbindd_free_response(&response);
- return(do_list(1,rq));
-
- case WINBINDD_GETGRENT:
- case WINBINDD_GETGRLST:
- {
- int entries;
-
- nsd_logprintf(NSD_LOG_MIN,
- "callback (winbind) GETGRENT | GETGRLIST %d responses\n",
- response.data.num_entries);
-
- if (response.data.num_entries) {
- const struct winbindd_gr *gr = &response.data.gr;
- const char * members;
- fstring grp_name;
- int i;
-
- gr = (struct winbindd_gr *)response.extra_data.data;
- if (! gr ) {
- nsd_logprintf(NSD_LOG_MIN, " no extra_data\n");
- winbindd_free_response(&response);
- return NSD_ERROR;
- }
-
- members = (char *)response.extra_data.data +
- (response.data.num_entries * sizeof(struct winbindd_gr));
-
- for (i = 0; i < response.data.num_entries; i++) {
- snprintf(grp_name, sizeof(grp_name) - 1, "%s:%s:%d:",
- gr->gr_name, gr->gr_passwd, gr->gr_gid);
-
- nsd_append_element(rq, NS_SUCCESS, result, rlen);
- nsd_append_result(rq, NS_SUCCESS,
- &members[gr->gr_mem_ofs],
- strlen(&members[gr->gr_mem_ofs]));
-
- /* Don't log the whole list, because it might be
- * _really_ long and we probably don't want to clobber
- * the log with it.
- */
- nsd_logprintf(NSD_LOG_MIN, " %s (...)\n", grp_name);
-
- gr++;
- }
- }
-
- entries = response.data.num_entries;
- winbindd_free_response(&response);
- if (entries < MAX_GETPWENT_USERS)
- return(do_list(2,rq));
- else
- return(do_list(1,rq));
- }
-
- case WINBINDD_GETPWENT:
- {
- int entries;
-
- nsd_logprintf(NSD_LOG_MIN,
- "callback (winbind) GETPWENT %d responses\n",
- response.data.num_entries);
-
- if (response.data.num_entries) {
- struct winbindd_pw *pw = &response.data.pw;
- int i;
-
- pw = (struct winbindd_pw *)response.extra_data.data;
- if (! pw ) {
- nsd_logprintf(NSD_LOG_MIN, " no extra_data\n");
- winbindd_free_response(&response);
- return NSD_ERROR;
- }
- for (i = 0; i < response.data.num_entries; i++) {
- result = NULL;
- rlen = asprintf(&result, "%s:%s:%d:%d:%s:%s:%s",
- pw->pw_name,
- pw->pw_passwd,
- pw->pw_uid,
- pw->pw_gid,
- pw->pw_gecos,
- pw->pw_dir,
- pw->pw_shell);
-
- if (rlen != 0 && result != NULL) {
- nsd_logprintf(NSD_LOG_MIN, " %s\n",result);
- nsd_append_element(rq, NS_SUCCESS, result, rlen);
- free(result);
- }
-
- pw++;
- }
- }
-
- entries = response.data.num_entries;
- winbindd_free_response(&response);
- if (entries < MAX_GETPWENT_USERS)
- return(do_list(2,rq));
- else
- return(do_list(1,rq));
- }
-
- case WINBINDD_ENDGRENT:
- case WINBINDD_ENDPWENT:
- nsd_logprintf(NSD_LOG_MIN, "callback (winbind) ENDGRENT | ENDPWENT\n");
- nsd_append_element(rq, NS_SUCCESS, "\n", 1);
- winbindd_free_response(&response);
- return NSD_NEXT;
-
- default:
- winbindd_free_response(&response);
- nsd_logprintf(NSD_LOG_MIN, "callback (winbind) invalid command %d\n", (int)rq->f_cmd_data);
- return NSD_NEXT;
- }
-}
-
-static int
-winbind_timeout(nsd_file_t **rqp, nsd_times_t *to)
-{
- nsd_file_t *rq;
-
- dequeue_request();
-
- nsd_logprintf(NSD_LOG_MIN, "timeout (winbind)\n");
-
- rq = to->t_file;
- *rqp = rq;
-
- /* Remove the callback and timeout */
- nsd_callback_remove(winbindd_fd);
- nsd_timeout_remove(rq);
-
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
-}
-
-static int
-send_next_request(nsd_file_t *rq, struct winbindd_request *request)
-{
- NSS_STATUS status;
- long timeout;
-
- switch (rq->f_index) {
- case LOOKUP:
- timeout = nsd_attr_fetch_long(rq->f_attrs,
- "lookup_timeout", 10, 10);
- break;
- case LIST:
- timeout = nsd_attr_fetch_long(rq->f_attrs,
- "list_timeout", 10, 10);
- break;
- default:
- nsd_logprintf(NSD_LOG_OPER,
- "send_next_request (winbind) "
- "invalid request type %d\n", rq->f_index);
- rq->f_status = NS_BADREQ;
- return NSD_NEXT;
- }
-
- nsd_logprintf(NSD_LOG_MIN,
- "send_next_request (winbind) %d, timeout = %d sec\n",
- rq->f_cmd_data, timeout);
- status = winbindd_send_request((int)rq->f_cmd_data,0,request);
- SAFE_FREE(request);
-
- if (status != NSS_STATUS_SUCCESS) {
- nsd_logprintf(NSD_LOG_MIN,
- "send_next_request (winbind) error status = %d\n",
- status);
- rq->f_status = status;
- return NSD_NEXT;
- }
-
- current_rq = rq;
-
- /*
- * Set up callback and timeouts
- */
- nsd_logprintf(NSD_LOG_MIN, "send_next_request (winbind) fd = %d\n",
- winbindd_fd);
-
- nsd_callback_new(winbindd_fd, winbind_callback, NSD_READ);
- nsd_timeout_new(rq, timeout * 1000, winbind_timeout, NULL);
- return NSD_CONTINUE;
-}
-
-int init(void)
-{
- nsd_logprintf(NSD_LOG_MIN, "entering init (winbind)\n");
- return(NSD_OK);
-}
-
-int lookup(nsd_file_t *rq)
-{
- char *map;
- char *key;
- struct winbindd_request *request;
-
- nsd_logprintf(NSD_LOG_MIN, "entering lookup (winbind)\n");
- if (! rq)
- return NSD_ERROR;
-
- map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0);
- key = nsd_attr_fetch_string(rq->f_attrs, "key", (char*)0);
- if (! map || ! key) {
- nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) table or key not defined\n");
- rq->f_status = NS_BADREQ;
- return NSD_ERROR;
- }
-
- nsd_logprintf(NSD_LOG_MIN, "lookup (winbind %s)\n",map);
-
- request = (struct winbindd_request *)nsd_calloc(1,sizeof(struct winbindd_request));
- if (! request) {
- nsd_logprintf(NSD_LOG_RESOURCE,
- "lookup (winbind): failed malloc\n");
- return NSD_ERROR;
- }
-
- if (strcasecmp(map,"passwd.byuid") == 0) {
- request->data.uid = atoi(key);
- rq->f_cmd_data = (void *)WINBINDD_GETPWUID;
- } else if (strcasecmp(map,"passwd.byname") == 0) {
- strncpy(request->data.username, key,
- sizeof(request->data.username) - 1);
- request->data.username[sizeof(request->data.username) - 1] = '\0';
- rq->f_cmd_data = (void *)WINBINDD_GETPWNAM;
- } else if (strcasecmp(map,"group.byname") == 0) {
- strncpy(request->data.groupname, key,
- sizeof(request->data.groupname) - 1);
- request->data.groupname[sizeof(request->data.groupname) - 1] = '\0';
- rq->f_cmd_data = (void *)WINBINDD_GETGRNAM;
- } else if (strcasecmp(map,"group.bygid") == 0) {
- request->data.gid = atoi(key);
- rq->f_cmd_data = (void *)WINBINDD_GETGRGID;
- } else if (strcasecmp(map,"hosts.byname") == 0) {
- strncpy(request->data.winsreq, key, sizeof(request->data.winsreq) - 1);
- request->data.winsreq[sizeof(request->data.winsreq) - 1] = '\0';
- rq->f_cmd_data = (void *)WINBINDD_WINS_BYNAME;
- } else if (strcasecmp(map,"hosts.byaddr") == 0) {
- strncpy(request->data.winsreq, key, sizeof(request->data.winsreq) - 1);
- request->data.winsreq[sizeof(request->data.winsreq) - 1] = '\0';
- rq->f_cmd_data = (void *)WINBINDD_WINS_BYIP;
- } else {
- /*
- * Don't understand this map - just return not found
- */
- nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) unknown table\n");
- SAFE_FREE(request);
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
- }
-
- return(do_request(rq, request));
-}
-
-int list(nsd_file_t *rq)
-{
- char *map;
-
- nsd_logprintf(NSD_LOG_MIN, "entering list (winbind)\n");
- if (! rq)
- return NSD_ERROR;
-
- map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0);
- if (! map ) {
- nsd_logprintf(NSD_LOG_MIN, "list (winbind) table not defined\n");
- rq->f_status = NS_BADREQ;
- return NSD_ERROR;
- }
-
- nsd_logprintf(NSD_LOG_MIN, "list (winbind %s)\n",map);
-
- return (do_list(0,rq));
-}
-
-static int
-do_list(int state, nsd_file_t *rq)
-{
- char *map;
- struct winbindd_request *request;
-
- nsd_logprintf(NSD_LOG_MIN, "entering do_list (winbind) state = %d\n",state);
-
- map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0);
- request = (struct winbindd_request *)nsd_calloc(1,sizeof(struct winbindd_request));
- if (! request) {
- nsd_logprintf(NSD_LOG_RESOURCE,
- "do_list (winbind): failed malloc\n");
- return NSD_ERROR;
- }
-
- if (strcasecmp(map,"passwd.byname") == 0) {
- switch (state) {
- case 0:
- rq->f_cmd_data = (void *)WINBINDD_SETPWENT;
- break;
- case 1:
- request->data.num_entries = MAX_GETPWENT_USERS;
- rq->f_cmd_data = (void *)WINBINDD_GETPWENT;
- break;
- case 2:
- rq->f_cmd_data = (void *)WINBINDD_ENDPWENT;
- break;
- default:
- nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown state\n");
- SAFE_FREE(request);
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
- }
- } else if (strcasecmp(map,"group.byname") == 0) {
- switch (state) {
- case 0:
- rq->f_cmd_data = (void *)WINBINDD_SETGRENT;
- break;
- case 1:
- request->data.num_entries = MAX_GETGRENT_USERS;
- rq->f_cmd_data = (void *)WINBINDD_GETGRENT;
- break;
- case 2:
- rq->f_cmd_data = (void *)WINBINDD_ENDGRENT;
- break;
- default:
- nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown state\n");
- SAFE_FREE(request);
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
- }
- } else {
- /*
- * Don't understand this map - just return not found
- */
- nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown table\n");
- SAFE_FREE(request);
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
- }
-
- return(do_request(rq, request));
-}
-
-#endif /* HAVE_NS_API_H */
diff --git a/source3/nsswitch/winbind_nss_irix.h b/source3/nsswitch/winbind_nss_irix.h
deleted file mode 100644
index b40b14b0b0..0000000000
--- a/source3/nsswitch/winbind_nss_irix.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon for ntdom nss module
-
- Copyright (C) Tim Potter 2000
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _WINBIND_NSS_IRIX_H
-#define _WINBIND_NSS_IRIX_H
-
-/* following required to prevent warnings of double definition
- * of datum from ns_api.h
-*/
-#ifdef DATUM
-#define _DATUM_DEFINED
-#endif
-
-#include <ns_api.h>
-
-typedef enum
-{
- NSS_STATUS_SUCCESS=NS_SUCCESS,
- NSS_STATUS_NOTFOUND=NS_NOTFOUND,
- NSS_STATUS_UNAVAIL=NS_UNAVAIL,
- NSS_STATUS_TRYAGAIN=NS_TRYAGAIN
-} NSS_STATUS;
-
-#endif /* _WINBIND_NSS_IRIX_H */
diff --git a/source3/nsswitch/winbind_nss_linux.c b/source3/nsswitch/winbind_nss_linux.c
deleted file mode 100644
index c11c18759e..0000000000
--- a/source3/nsswitch/winbind_nss_linux.c
+++ /dev/null
@@ -1,1477 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Windows NT Domain nsswitch module
-
- Copyright (C) Tim Potter 2000
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "winbind_client.h"
-
-#if HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
-
-#if HAVE_PTHREAD
-static pthread_mutex_t winbind_nss_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif
-
-/* Maximum number of users to pass back over the unix domain socket
- per call. This is not a static limit on the total number of users
- or groups returned in total. */
-
-#define MAX_GETPWENT_USERS 250
-#define MAX_GETGRENT_USERS 250
-
-NSS_STATUS _nss_winbind_setpwent(void);
-NSS_STATUS _nss_winbind_endpwent(void);
-NSS_STATUS _nss_winbind_getpwent_r(struct passwd *result, char *buffer,
- size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_getpwuid_r(uid_t uid, struct passwd *result,
- char *buffer, size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_getpwnam_r(const char *name, struct passwd *result,
- char *buffer, size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_setgrent(void);
-NSS_STATUS _nss_winbind_endgrent(void);
-NSS_STATUS _nss_winbind_getgrent_r(struct group *result, char *buffer,
- size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_getgrlst_r(struct group *result, char *buffer,
- size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_getgrnam_r(const char *name, struct group *result,
- char *buffer, size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_getgrgid_r(gid_t gid, struct group *result, char *buffer,
- size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start,
- long int *size, gid_t **groups,
- long int limit, int *errnop);
-NSS_STATUS _nss_winbind_getusersids(const char *user_sid, char **group_sids,
- int *num_groups, char *buffer, size_t buf_size,
- int *errnop);
-NSS_STATUS _nss_winbind_nametosid(const char *name, char **sid, char *buffer,
- size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_sidtoname(const char *sid, char **name, char *buffer,
- size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_sidtouid(const char *sid, uid_t *uid, int *errnop);
-NSS_STATUS _nss_winbind_sidtogid(const char *sid, gid_t *gid, int *errnop);
-NSS_STATUS _nss_winbind_uidtosid(uid_t uid, char **sid, char *buffer,
- size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_gidtosid(gid_t gid, char **sid, char *buffer,
- size_t buflen, int *errnop);
-
-/* Prototypes from wb_common.c */
-
-/* Allocate some space from the nss static buffer. The buffer and buflen
- are the pointers passed in by the C library to the _nss_ntdom_*
- functions. */
-
-static char *get_static(char **buffer, size_t *buflen, size_t len)
-{
- char *result;
-
- /* Error check. We return false if things aren't set up right, or
- there isn't enough buffer space left. */
-
- if ((buffer == NULL) || (buflen == NULL) || (*buflen < len)) {
- return NULL;
- }
-
- /* Return an index into the static buffer */
-
- result = *buffer;
- *buffer += len;
- *buflen -= len;
-
- return result;
-}
-
-/* I've copied the strtok() replacement function next_token_Xalloc() from
- lib/util_str.c as I really don't want to have to link in any other
- objects if I can possibly avoid it. */
-
-static bool next_token_alloc(const char **ptr,
- char **pp_buff,
- const char *sep)
-{
- char *s;
- char *saved_s;
- char *pbuf;
- bool quoted;
- size_t len=1;
-
- *pp_buff = NULL;
- if (!ptr) {
- return(false);
- }
-
- s = (char *)*ptr;
-
- /* default to simple separators */
- if (!sep) {
- sep = " \t\n\r";
- }
-
- /* find the first non sep char */
- while (*s && strchr(sep,*s)) {
- s++;
- }
-
- /* nothing left? */
- if (!*s) {
- return false;
- }
-
- /* When restarting we need to go from here. */
- saved_s = s;
-
- /* Work out the length needed. */
- for (quoted = false; *s &&
- (quoted || !strchr(sep,*s)); s++) {
- if (*s == '\"') {
- quoted = !quoted;
- } else {
- len++;
- }
- }
-
- /* We started with len = 1 so we have space for the nul. */
- *pp_buff = (char *)malloc(len);
- if (!*pp_buff) {
- return false;
- }
-
- /* copy over the token */
- pbuf = *pp_buff;
- s = saved_s;
- for (quoted = false; *s &&
- (quoted || !strchr(sep,*s)); s++) {
- if ( *s == '\"' ) {
- quoted = !quoted;
- } else {
- *pbuf++ = *s;
- }
- }
-
- *ptr = (*s) ? s+1 : s;
- *pbuf = 0;
-
- return true;
-}
-
-/* Fill a pwent structure from a winbindd_response structure. We use
- the static data passed to us by libc to put strings and stuff in.
- Return NSS_STATUS_TRYAGAIN if we run out of memory. */
-
-static NSS_STATUS fill_pwent(struct passwd *result,
- struct winbindd_pw *pw,
- char **buffer, size_t *buflen)
-{
- /* User name */
-
- if ((result->pw_name =
- get_static(buffer, buflen, strlen(pw->pw_name) + 1)) == NULL) {
-
- /* Out of memory */
-
- return NSS_STATUS_TRYAGAIN;
- }
-
- strcpy(result->pw_name, pw->pw_name);
-
- /* Password */
-
- if ((result->pw_passwd =
- get_static(buffer, buflen, strlen(pw->pw_passwd) + 1)) == NULL) {
-
- /* Out of memory */
-
- return NSS_STATUS_TRYAGAIN;
- }
-
- strcpy(result->pw_passwd, pw->pw_passwd);
-
- /* [ug]id */
-
- result->pw_uid = pw->pw_uid;
- result->pw_gid = pw->pw_gid;
-
- /* GECOS */
-
- if ((result->pw_gecos =
- get_static(buffer, buflen, strlen(pw->pw_gecos) + 1)) == NULL) {
-
- /* Out of memory */
-
- return NSS_STATUS_TRYAGAIN;
- }
-
- strcpy(result->pw_gecos, pw->pw_gecos);
-
- /* Home directory */
-
- if ((result->pw_dir =
- get_static(buffer, buflen, strlen(pw->pw_dir) + 1)) == NULL) {
-
- /* Out of memory */
-
- return NSS_STATUS_TRYAGAIN;
- }
-
- strcpy(result->pw_dir, pw->pw_dir);
-
- /* Logon shell */
-
- if ((result->pw_shell =
- get_static(buffer, buflen, strlen(pw->pw_shell) + 1)) == NULL) {
-
- /* Out of memory */
-
- return NSS_STATUS_TRYAGAIN;
- }
-
- strcpy(result->pw_shell, pw->pw_shell);
-
- /* The struct passwd for Solaris has some extra fields which must
- be initialised or nscd crashes. */
-
-#if HAVE_PASSWD_PW_COMMENT
- result->pw_comment = "";
-#endif
-
-#if HAVE_PASSWD_PW_AGE
- result->pw_age = "";
-#endif
-
- return NSS_STATUS_SUCCESS;
-}
-
-/* Fill a grent structure from a winbindd_response structure. We use
- the static data passed to us by libc to put strings and stuff in.
- Return NSS_STATUS_TRYAGAIN if we run out of memory. */
-
-static NSS_STATUS fill_grent(struct group *result, struct winbindd_gr *gr,
- char *gr_mem, char **buffer, size_t *buflen)
-{
- char *name;
- int i;
- char *tst;
-
- /* Group name */
-
- if ((result->gr_name =
- get_static(buffer, buflen, strlen(gr->gr_name) + 1)) == NULL) {
-
- /* Out of memory */
-
- return NSS_STATUS_TRYAGAIN;
- }
-
- strcpy(result->gr_name, gr->gr_name);
-
- /* Password */
-
- if ((result->gr_passwd =
- get_static(buffer, buflen, strlen(gr->gr_passwd) + 1)) == NULL) {
-
- /* Out of memory */
- return NSS_STATUS_TRYAGAIN;
- }
-
- strcpy(result->gr_passwd, gr->gr_passwd);
-
- /* gid */
-
- result->gr_gid = gr->gr_gid;
-
- /* Group membership */
-
- if ((gr->num_gr_mem < 0) || !gr_mem) {
- gr->num_gr_mem = 0;
- }
-
- /* this next value is a pointer to a pointer so let's align it */
-
- /* Calculate number of extra bytes needed to align on pointer size boundry */
- if ((i = (unsigned long)(*buffer) % sizeof(char*)) != 0)
- i = sizeof(char*) - i;
-
- if ((tst = get_static(buffer, buflen, ((gr->num_gr_mem + 1) *
- sizeof(char *)+i))) == NULL) {
-
- /* Out of memory */
-
- return NSS_STATUS_TRYAGAIN;
- }
- result->gr_mem = (char **)(tst + i);
-
- if (gr->num_gr_mem == 0) {
-
- /* Group is empty */
-
- *(result->gr_mem) = NULL;
- return NSS_STATUS_SUCCESS;
- }
-
- /* Start looking at extra data */
-
- i = 0;
-
- while(next_token_alloc((const char **)&gr_mem, &name, ",")) {
- /* Allocate space for member */
- if (((result->gr_mem)[i] =
- get_static(buffer, buflen, strlen(name) + 1)) == NULL) {
- free(name);
- /* Out of memory */
- return NSS_STATUS_TRYAGAIN;
- }
- strcpy((result->gr_mem)[i], name);
- free(name);
- i++;
- }
-
- /* Terminate list */
-
- (result->gr_mem)[i] = NULL;
-
- return NSS_STATUS_SUCCESS;
-}
-
-/*
- * NSS user functions
- */
-
-static struct winbindd_response getpwent_response;
-
-static int ndx_pw_cache; /* Current index into pwd cache */
-static int num_pw_cache; /* Current size of pwd cache */
-
-/* Rewind "file pointer" to start of ntdom password database */
-
-NSS_STATUS
-_nss_winbind_setpwent(void)
-{
- NSS_STATUS ret;
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: setpwent\n", getpid());
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&winbind_nss_mutex);
-#endif
-
- if (num_pw_cache > 0) {
- ndx_pw_cache = num_pw_cache = 0;
- winbindd_free_response(&getpwent_response);
- }
-
- ret = winbindd_request_response(WINBINDD_SETPWENT, NULL, NULL);
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: setpwent returns %s (%d)\n", getpid(),
- nss_err_str(ret), ret);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&winbind_nss_mutex);
-#endif
- return ret;
-}
-
-/* Close ntdom password database "file pointer" */
-
-NSS_STATUS
-_nss_winbind_endpwent(void)
-{
- NSS_STATUS ret;
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: endpwent\n", getpid());
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&winbind_nss_mutex);
-#endif
-
- if (num_pw_cache > 0) {
- ndx_pw_cache = num_pw_cache = 0;
- winbindd_free_response(&getpwent_response);
- }
-
- ret = winbindd_request_response(WINBINDD_ENDPWENT, NULL, NULL);
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: endpwent returns %s (%d)\n", getpid(),
- nss_err_str(ret), ret);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&winbind_nss_mutex);
-#endif
-
- return ret;
-}
-
-/* Fetch the next password entry from ntdom password database */
-
-NSS_STATUS
-_nss_winbind_getpwent_r(struct passwd *result, char *buffer,
- size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- struct winbindd_request request;
- static int called_again;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getpwent\n", getpid());
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&winbind_nss_mutex);
-#endif
-
- /* Return an entry from the cache if we have one, or if we are
- called again because we exceeded our static buffer. */
-
- if ((ndx_pw_cache < num_pw_cache) || called_again) {
- goto return_result;
- }
-
- /* Else call winbindd to get a bunch of entries */
-
- if (num_pw_cache > 0) {
- winbindd_free_response(&getpwent_response);
- }
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(getpwent_response);
-
- request.data.num_entries = MAX_GETPWENT_USERS;
-
- ret = winbindd_request_response(WINBINDD_GETPWENT, &request,
- &getpwent_response);
-
- if (ret == NSS_STATUS_SUCCESS) {
- struct winbindd_pw *pw_cache;
-
- /* Fill cache */
-
- ndx_pw_cache = 0;
- num_pw_cache = getpwent_response.data.num_entries;
-
- /* Return a result */
-
- return_result:
-
- pw_cache = (struct winbindd_pw *)
- getpwent_response.extra_data.data;
-
- /* Check data is valid */
-
- if (pw_cache == NULL) {
- ret = NSS_STATUS_NOTFOUND;
- goto done;
- }
-
- ret = fill_pwent(result, &pw_cache[ndx_pw_cache],
- &buffer, &buflen);
-
- /* Out of memory - try again */
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- called_again = true;
- *errnop = errno = ERANGE;
- goto done;
- }
-
- *errnop = errno = 0;
- called_again = false;
- ndx_pw_cache++;
-
- /* If we've finished with this lot of results free cache */
-
- if (ndx_pw_cache == num_pw_cache) {
- ndx_pw_cache = num_pw_cache = 0;
- winbindd_free_response(&getpwent_response);
- }
- }
- done:
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getpwent returns %s (%d)\n", getpid(),
- nss_err_str(ret), ret);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&winbind_nss_mutex);
-#endif
- return ret;
-}
-
-/* Return passwd struct from uid */
-
-NSS_STATUS
-_nss_winbind_getpwuid_r(uid_t uid, struct passwd *result, char *buffer,
- size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- static struct winbindd_response response;
- struct winbindd_request request;
- static int keep_response;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getpwuid_r %d\n", getpid(), (unsigned int)uid);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&winbind_nss_mutex);
-#endif
-
- /* If our static buffer needs to be expanded we are called again */
- if (!keep_response || uid != response.data.pw.pw_uid) {
-
- /* Call for the first time */
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- request.data.uid = uid;
-
- ret = winbindd_request_response(WINBINDD_GETPWUID, &request, &response);
-
- if (ret == NSS_STATUS_SUCCESS) {
- ret = fill_pwent(result, &response.data.pw,
- &buffer, &buflen);
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- keep_response = true;
- *errnop = errno = ERANGE;
- goto done;
- }
- }
-
- } else {
-
- /* We've been called again */
-
- ret = fill_pwent(result, &response.data.pw, &buffer, &buflen);
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- *errnop = errno = ERANGE;
- goto done;
- }
-
- keep_response = false;
- *errnop = errno = 0;
- }
-
- winbindd_free_response(&response);
-
- done:
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getpwuid %d returns %s (%d)\n", getpid(),
- (unsigned int)uid, nss_err_str(ret), ret);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&winbind_nss_mutex);
-#endif
-
- return ret;
-}
-
-/* Return passwd struct from username */
-NSS_STATUS
-_nss_winbind_getpwnam_r(const char *name, struct passwd *result, char *buffer,
- size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- static struct winbindd_response response;
- struct winbindd_request request;
- static int keep_response;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getpwnam_r %s\n", getpid(), name);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&winbind_nss_mutex);
-#endif
-
- /* If our static buffer needs to be expanded we are called again */
-
- if (!keep_response || strcmp(name,response.data.pw.pw_name) != 0) {
-
- /* Call for the first time */
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- strncpy(request.data.username, name,
- sizeof(request.data.username) - 1);
- request.data.username
- [sizeof(request.data.username) - 1] = '\0';
-
- ret = winbindd_request_response(WINBINDD_GETPWNAM, &request, &response);
-
- if (ret == NSS_STATUS_SUCCESS) {
- ret = fill_pwent(result, &response.data.pw, &buffer,
- &buflen);
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- keep_response = true;
- *errnop = errno = ERANGE;
- goto done;
- }
- }
-
- } else {
-
- /* We've been called again */
-
- ret = fill_pwent(result, &response.data.pw, &buffer, &buflen);
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- keep_response = true;
- *errnop = errno = ERANGE;
- goto done;
- }
-
- keep_response = false;
- *errnop = errno = 0;
- }
-
- winbindd_free_response(&response);
- done:
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getpwnam %s returns %s (%d)\n", getpid(),
- name, nss_err_str(ret), ret);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&winbind_nss_mutex);
-#endif
-
- return ret;
-}
-
-/*
- * NSS group functions
- */
-
-static struct winbindd_response getgrent_response;
-
-static int ndx_gr_cache; /* Current index into grp cache */
-static int num_gr_cache; /* Current size of grp cache */
-
-/* Rewind "file pointer" to start of ntdom group database */
-
-NSS_STATUS
-_nss_winbind_setgrent(void)
-{
- NSS_STATUS ret;
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: setgrent\n", getpid());
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&winbind_nss_mutex);
-#endif
-
- if (num_gr_cache > 0) {
- ndx_gr_cache = num_gr_cache = 0;
- winbindd_free_response(&getgrent_response);
- }
-
- ret = winbindd_request_response(WINBINDD_SETGRENT, NULL, NULL);
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: setgrent returns %s (%d)\n", getpid(),
- nss_err_str(ret), ret);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&winbind_nss_mutex);
-#endif
-
- return ret;
-}
-
-/* Close "file pointer" for ntdom group database */
-
-NSS_STATUS
-_nss_winbind_endgrent(void)
-{
- NSS_STATUS ret;
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: endgrent\n", getpid());
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&winbind_nss_mutex);
-#endif
-
- if (num_gr_cache > 0) {
- ndx_gr_cache = num_gr_cache = 0;
- winbindd_free_response(&getgrent_response);
- }
-
- ret = winbindd_request_response(WINBINDD_ENDGRENT, NULL, NULL);
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: endgrent returns %s (%d)\n", getpid(),
- nss_err_str(ret), ret);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&winbind_nss_mutex);
-#endif
-
- return ret;
-}
-
-/* Get next entry from ntdom group database */
-
-static NSS_STATUS
-winbind_getgrent(enum winbindd_cmd cmd,
- struct group *result,
- char *buffer, size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- static struct winbindd_request request;
- static int called_again;
-
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getgrent\n", getpid());
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&winbind_nss_mutex);
-#endif
-
- /* Return an entry from the cache if we have one, or if we are
- called again because we exceeded our static buffer. */
-
- if ((ndx_gr_cache < num_gr_cache) || called_again) {
- goto return_result;
- }
-
- /* Else call winbindd to get a bunch of entries */
-
- if (num_gr_cache > 0) {
- winbindd_free_response(&getgrent_response);
- }
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(getgrent_response);
-
- request.data.num_entries = MAX_GETGRENT_USERS;
-
- ret = winbindd_request_response(cmd, &request,
- &getgrent_response);
-
- if (ret == NSS_STATUS_SUCCESS) {
- struct winbindd_gr *gr_cache;
- int mem_ofs;
-
- /* Fill cache */
-
- ndx_gr_cache = 0;
- num_gr_cache = getgrent_response.data.num_entries;
-
- /* Return a result */
-
- return_result:
-
- gr_cache = (struct winbindd_gr *)
- getgrent_response.extra_data.data;
-
- /* Check data is valid */
-
- if (gr_cache == NULL) {
- ret = NSS_STATUS_NOTFOUND;
- goto done;
- }
-
- /* Fill group membership. The offset into the extra data
- for the group membership is the reported offset plus the
- size of all the winbindd_gr records returned. */
-
- mem_ofs = gr_cache[ndx_gr_cache].gr_mem_ofs +
- num_gr_cache * sizeof(struct winbindd_gr);
-
- ret = fill_grent(result, &gr_cache[ndx_gr_cache],
- ((char *)getgrent_response.extra_data.data)+mem_ofs,
- &buffer, &buflen);
-
- /* Out of memory - try again */
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- called_again = true;
- *errnop = errno = ERANGE;
- goto done;
- }
-
- *errnop = 0;
- called_again = false;
- ndx_gr_cache++;
-
- /* If we've finished with this lot of results free cache */
-
- if (ndx_gr_cache == num_gr_cache) {
- ndx_gr_cache = num_gr_cache = 0;
- winbindd_free_response(&getgrent_response);
- }
- }
- done:
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getgrent returns %s (%d)\n", getpid(),
- nss_err_str(ret), ret);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&winbind_nss_mutex);
-#endif
-
- return ret;
-}
-
-
-NSS_STATUS
-_nss_winbind_getgrent_r(struct group *result,
- char *buffer, size_t buflen, int *errnop)
-{
- return winbind_getgrent(WINBINDD_GETGRENT, result, buffer, buflen, errnop);
-}
-
-NSS_STATUS
-_nss_winbind_getgrlst_r(struct group *result,
- char *buffer, size_t buflen, int *errnop)
-{
- return winbind_getgrent(WINBINDD_GETGRLST, result, buffer, buflen, errnop);
-}
-
-/* Return group struct from group name */
-
-NSS_STATUS
-_nss_winbind_getgrnam_r(const char *name,
- struct group *result, char *buffer,
- size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- static struct winbindd_response response;
- struct winbindd_request request;
- static int keep_response;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getgrnam %s\n", getpid(), name);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&winbind_nss_mutex);
-#endif
-
- /* If our static buffer needs to be expanded we are called again */
- /* Or if the stored response group name differs from the request. */
-
- if (!keep_response || strcmp(name,response.data.gr.gr_name) != 0) {
-
- /* Call for the first time */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- strncpy(request.data.groupname, name,
- sizeof(request.data.groupname));
- request.data.groupname
- [sizeof(request.data.groupname) - 1] = '\0';
-
- ret = winbindd_request_response(WINBINDD_GETGRNAM, &request, &response);
-
- if (ret == NSS_STATUS_SUCCESS) {
- ret = fill_grent(result, &response.data.gr,
- (char *)response.extra_data.data,
- &buffer, &buflen);
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- keep_response = true;
- *errnop = errno = ERANGE;
- goto done;
- }
- }
-
- } else {
-
- /* We've been called again */
-
- ret = fill_grent(result, &response.data.gr,
- (char *)response.extra_data.data, &buffer,
- &buflen);
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- keep_response = true;
- *errnop = errno = ERANGE;
- goto done;
- }
-
- keep_response = false;
- *errnop = 0;
- }
-
- winbindd_free_response(&response);
- done:
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getgrnam %s returns %s (%d)\n", getpid(),
- name, nss_err_str(ret), ret);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&winbind_nss_mutex);
-#endif
-
- return ret;
-}
-
-/* Return group struct from gid */
-
-NSS_STATUS
-_nss_winbind_getgrgid_r(gid_t gid,
- struct group *result, char *buffer,
- size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- static struct winbindd_response response;
- struct winbindd_request request;
- static int keep_response;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getgrgid %d\n", getpid(), gid);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&winbind_nss_mutex);
-#endif
-
- /* If our static buffer needs to be expanded we are called again */
- /* Or if the stored response group name differs from the request. */
-
- if (!keep_response || gid != response.data.gr.gr_gid) {
-
- /* Call for the first time */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- request.data.gid = gid;
-
- ret = winbindd_request_response(WINBINDD_GETGRGID, &request, &response);
-
- if (ret == NSS_STATUS_SUCCESS) {
-
- ret = fill_grent(result, &response.data.gr,
- (char *)response.extra_data.data,
- &buffer, &buflen);
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- keep_response = true;
- *errnop = errno = ERANGE;
- goto done;
- }
- }
-
- } else {
-
- /* We've been called again */
-
- ret = fill_grent(result, &response.data.gr,
- (char *)response.extra_data.data, &buffer,
- &buflen);
-
- if (ret == NSS_STATUS_TRYAGAIN) {
- keep_response = true;
- *errnop = errno = ERANGE;
- goto done;
- }
-
- keep_response = false;
- *errnop = 0;
- }
-
- winbindd_free_response(&response);
- done:
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getgrgid %d returns %s (%d)\n", getpid(),
- (unsigned int)gid, nss_err_str(ret), ret);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&winbind_nss_mutex);
-#endif
- return ret;
-}
-
-/* Initialise supplementary groups */
-
-NSS_STATUS
-_nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start,
- long int *size, gid_t **groups, long int limit,
- int *errnop)
-{
- NSS_STATUS ret;
- struct winbindd_request request;
- struct winbindd_response response;
- int i;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: initgroups %s (%d)\n", getpid(),
- user, group);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&winbind_nss_mutex);
-#endif
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- strncpy(request.data.username, user,
- sizeof(request.data.username) - 1);
-
- ret = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response);
-
- if (ret == NSS_STATUS_SUCCESS) {
- int num_gids = response.data.num_entries;
- gid_t *gid_list = (gid_t *)response.extra_data.data;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: initgroups %s: got NSS_STATUS_SUCCESS "
- "and %d gids\n", getpid(),
- user, num_gids);
-#endif
- if (gid_list == NULL) {
- ret = NSS_STATUS_NOTFOUND;
- goto done;
- }
-
- /* Copy group list to client */
-
- for (i = 0; i < num_gids; i++) {
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: initgroups %s (%d): "
- "processing gid %d \n", getpid(),
- user, group, gid_list[i]);
-#endif
-
- /* Skip primary group */
-
- if (gid_list[i] == group) {
- continue;
- }
-
- /* Filled buffer ? If so, resize. */
-
- if (*start == *size) {
- long int newsize;
- gid_t *newgroups;
-
- newsize = 2 * (*size);
- if (limit > 0) {
- if (*size == limit) {
- goto done;
- }
- if (newsize > limit) {
- newsize = limit;
- }
- }
-
- newgroups = (gid_t *)
- realloc((*groups),
- newsize * sizeof(**groups));
- if (!newgroups) {
- *errnop = ENOMEM;
- ret = NSS_STATUS_NOTFOUND;
- goto done;
- }
- *groups = newgroups;
- *size = newsize;
- }
-
- /* Add to buffer */
-
- (*groups)[*start] = gid_list[i];
- *start += 1;
- }
- }
-
- /* Back to your regularly scheduled programming */
-
- done:
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: initgroups %s returns %s (%d)\n", getpid(),
- user, nss_err_str(ret), ret);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&winbind_nss_mutex);
-#endif
-
- return ret;
-}
-
-
-/* return a list of group SIDs for a user SID */
-NSS_STATUS
-_nss_winbind_getusersids(const char *user_sid, char **group_sids,
- int *num_groups,
- char *buffer, size_t buf_size, int *errnop)
-{
- NSS_STATUS ret;
- struct winbindd_request request;
- struct winbindd_response response;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: getusersids %s\n", getpid(), user_sid);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&winbind_nss_mutex);
-#endif
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- strncpy(request.data.sid, user_sid,sizeof(request.data.sid) - 1);
- request.data.sid[sizeof(request.data.sid) - 1] = '\0';
-
- ret = winbindd_request_response(WINBINDD_GETUSERSIDS, &request, &response);
-
- if (ret != NSS_STATUS_SUCCESS) {
- goto done;
- }
-
- if (buf_size < response.length - sizeof(response)) {
- ret = NSS_STATUS_TRYAGAIN;
- errno = *errnop = ERANGE;
- goto done;
- }
-
- *num_groups = response.data.num_entries;
- *group_sids = buffer;
- memcpy(buffer, response.extra_data.data, response.length - sizeof(response));
- errno = *errnop = 0;
-
- done:
- winbindd_free_response(&response);
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&winbind_nss_mutex);
-#endif
-
- return ret;
-}
-
-
-/* map a user or group name to a SID string */
-NSS_STATUS
-_nss_winbind_nametosid(const char *name, char **sid, char *buffer,
- size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- struct winbindd_response response;
- struct winbindd_request request;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: nametosid %s\n", getpid(), name);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&winbind_nss_mutex);
-#endif
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- strncpy(request.data.name.name, name,
- sizeof(request.data.name.name) - 1);
- request.data.name.name[sizeof(request.data.name.name) - 1] = '\0';
-
- ret = winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response);
- if (ret != NSS_STATUS_SUCCESS) {
- *errnop = errno = EINVAL;
- goto failed;
- }
-
- if (buflen < strlen(response.data.sid.sid)+1) {
- ret = NSS_STATUS_TRYAGAIN;
- *errnop = errno = ERANGE;
- goto failed;
- }
-
- *errnop = errno = 0;
- *sid = buffer;
- strcpy(*sid, response.data.sid.sid);
-
-failed:
- winbindd_free_response(&response);
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&winbind_nss_mutex);
-#endif
-
- return ret;
-}
-
-/* map a sid string to a user or group name */
-NSS_STATUS
-_nss_winbind_sidtoname(const char *sid, char **name, char *buffer,
- size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- struct winbindd_response response;
- struct winbindd_request request;
- static char sep_char;
- unsigned needed;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: sidtoname %s\n", getpid(), sid);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&winbind_nss_mutex);
-#endif
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- /* we need to fetch the separator first time through */
- if (!sep_char) {
- ret = winbindd_request_response(WINBINDD_INFO, &request, &response);
- if (ret != NSS_STATUS_SUCCESS) {
- *errnop = errno = EINVAL;
- goto failed;
- }
-
- sep_char = response.data.info.winbind_separator;
- winbindd_free_response(&response);
- }
-
-
- strncpy(request.data.sid, sid,
- sizeof(request.data.sid) - 1);
- request.data.sid[sizeof(request.data.sid) - 1] = '\0';
-
- ret = winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response);
- if (ret != NSS_STATUS_SUCCESS) {
- *errnop = errno = EINVAL;
- goto failed;
- }
-
- needed =
- strlen(response.data.name.dom_name) +
- strlen(response.data.name.name) + 2;
-
- if (buflen < needed) {
- ret = NSS_STATUS_TRYAGAIN;
- *errnop = errno = ERANGE;
- goto failed;
- }
-
- snprintf(buffer, needed, "%s%c%s",
- response.data.name.dom_name,
- sep_char,
- response.data.name.name);
-
- *name = buffer;
- *errnop = errno = 0;
-
-failed:
- winbindd_free_response(&response);
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&winbind_nss_mutex);
-#endif
-
- return ret;
-}
-
-/* map a sid to a uid */
-NSS_STATUS
-_nss_winbind_sidtouid(const char *sid, uid_t *uid, int *errnop)
-{
- NSS_STATUS ret;
- struct winbindd_response response;
- struct winbindd_request request;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: sidtouid %s\n", getpid(), sid);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&winbind_nss_mutex);
-#endif
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- strncpy(request.data.sid, sid, sizeof(request.data.sid) - 1);
- request.data.sid[sizeof(request.data.sid) - 1] = '\0';
-
- ret = winbindd_request_response(WINBINDD_SID_TO_UID, &request, &response);
- if (ret != NSS_STATUS_SUCCESS) {
- *errnop = errno = EINVAL;
- goto failed;
- }
-
- *uid = response.data.uid;
-
-failed:
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&winbind_nss_mutex);
-#endif
-
- return ret;
-}
-
-/* map a sid to a gid */
-NSS_STATUS
-_nss_winbind_sidtogid(const char *sid, gid_t *gid, int *errnop)
-{
- NSS_STATUS ret;
- struct winbindd_response response;
- struct winbindd_request request;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5d]: sidtogid %s\n", getpid(), sid);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&winbind_nss_mutex);
-#endif
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- strncpy(request.data.sid, sid, sizeof(request.data.sid) - 1);
- request.data.sid[sizeof(request.data.sid) - 1] = '\0';
-
- ret = winbindd_request_response(WINBINDD_SID_TO_GID, &request, &response);
- if (ret != NSS_STATUS_SUCCESS) {
- *errnop = errno = EINVAL;
- goto failed;
- }
-
- *gid = response.data.gid;
-
-failed:
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&winbind_nss_mutex);
-#endif
-
- return ret;
-}
-
-/* map a uid to a SID string */
-NSS_STATUS
-_nss_winbind_uidtosid(uid_t uid, char **sid, char *buffer,
- size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- struct winbindd_response response;
- struct winbindd_request request;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5u]: uidtosid %u\n", (unsigned int)getpid(), (unsigned int)uid);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&winbind_nss_mutex);
-#endif
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- request.data.uid = uid;
-
- ret = winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response);
- if (ret != NSS_STATUS_SUCCESS) {
- *errnop = errno = EINVAL;
- goto failed;
- }
-
- if (buflen < strlen(response.data.sid.sid)+1) {
- ret = NSS_STATUS_TRYAGAIN;
- *errnop = errno = ERANGE;
- goto failed;
- }
-
- *errnop = errno = 0;
- *sid = buffer;
- strcpy(*sid, response.data.sid.sid);
-
-failed:
- winbindd_free_response(&response);
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&winbind_nss_mutex);
-#endif
-
- return ret;
-}
-
-/* map a gid to a SID string */
-NSS_STATUS
-_nss_winbind_gidtosid(gid_t gid, char **sid, char *buffer,
- size_t buflen, int *errnop)
-{
- NSS_STATUS ret;
- struct winbindd_response response;
- struct winbindd_request request;
-
-#ifdef DEBUG_NSS
- fprintf(stderr, "[%5u]: gidtosid %u\n", (unsigned int)getpid(), (unsigned int)gid);
-#endif
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&winbind_nss_mutex);
-#endif
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- request.data.gid = gid;
-
- ret = winbindd_request_response(WINBINDD_GID_TO_SID, &request, &response);
- if (ret != NSS_STATUS_SUCCESS) {
- *errnop = errno = EINVAL;
- goto failed;
- }
-
- if (buflen < strlen(response.data.sid.sid)+1) {
- ret = NSS_STATUS_TRYAGAIN;
- *errnop = errno = ERANGE;
- goto failed;
- }
-
- *errnop = errno = 0;
- *sid = buffer;
- strcpy(*sid, response.data.sid.sid);
-
-failed:
- winbindd_free_response(&response);
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&winbind_nss_mutex);
-#endif
-
- return ret;
-}
diff --git a/source3/nsswitch/winbind_nss_linux.h b/source3/nsswitch/winbind_nss_linux.h
deleted file mode 100644
index 74aaec5ce6..0000000000
--- a/source3/nsswitch/winbind_nss_linux.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon for ntdom nss module
-
- Copyright (C) Tim Potter 2000
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _WINBIND_NSS_LINUX_H
-#define _WINBIND_NSS_LINUX_H
-
-#include <nss.h>
-
-typedef enum nss_status NSS_STATUS;
-
-#endif /* _WINBIND_NSS_LINUX_H */
diff --git a/source3/nsswitch/winbind_nss_netbsd.c b/source3/nsswitch/winbind_nss_netbsd.c
deleted file mode 100644
index 9b8e0a2265..0000000000
--- a/source3/nsswitch/winbind_nss_netbsd.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- NetBSD loadable authentication module, providing identification
- routines against Samba winbind/Windows NT Domain
-
- Copyright (C) Luke Mewburn 2004-2005
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-
-#include "winbind_client.h"
-
-#include <sys/param.h>
-#include <stdarg.h>
-#include <syslog.h>
-
- /* dynamic nsswitch with "new" getpw* nsdispatch API available */
-#if defined(NSS_MODULE_INTERFACE_VERSION) && defined(HAVE_GETPWENT_R)
-
-/*
- group functions
- ---------------
-*/
-
-static struct group _winbind_group;
-static char _winbind_groupbuf[1024];
-
-/*
- * We need a proper prototype for this :-)
- */
-
-NSS_STATUS _nss_winbind_setpwent(void);
-NSS_STATUS _nss_winbind_endpwent(void);
-NSS_STATUS _nss_winbind_getpwent_r(struct passwd *result, char *buffer,
- size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_getpwuid_r(uid_t uid, struct passwd *result,
- char *buffer, size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_getpwnam_r(const char *name, struct passwd *result,
- char *buffer, size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_setgrent(void);
-NSS_STATUS _nss_winbind_endgrent(void);
-NSS_STATUS _nss_winbind_getgrent_r(struct group *result, char *buffer,
- size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_getgrlst_r(struct group *result, char *buffer,
- size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_getgrnam_r(const char *name, struct group *result,
- char *buffer, size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_getgrgid_r(gid_t gid, struct group *result, char *buffer,
- size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start,
- long int *size, gid_t **groups,
- long int limit, int *errnop);
-NSS_STATUS _nss_winbind_getusersids(const char *user_sid, char **group_sids,
- int *num_groups, char *buffer, size_t buf_size,
- int *errnop);
-NSS_STATUS _nss_winbind_nametosid(const char *name, char **sid, char *buffer,
- size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_sidtoname(const char *sid, char **name, char *buffer,
- size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_sidtouid(const char *sid, uid_t *uid, int *errnop);
-NSS_STATUS _nss_winbind_sidtogid(const char *sid, gid_t *gid, int *errnop);
-NSS_STATUS _nss_winbind_uidtosid(uid_t uid, char **sid, char *buffer,
- size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_gidtosid(gid_t gid, char **sid, char *buffer,
- size_t buflen, int *errnop);
-
-int
-netbsdwinbind_endgrent(void *nsrv, void *nscb, va_list ap)
-{
- int rv;
-
- rv = _nss_winbind_endgrent();
- return rv;
-}
-
-int
-netbsdwinbind_setgrent(void *nsrv, void *nscb, va_list ap)
-{
- int rv;
-
- rv = _nss_winbind_setgrent();
- return rv;
-}
-
-int
-netbsdwinbind_getgrent(void *nsrv, void *nscb, va_list ap)
-{
- struct group **retval = va_arg(ap, struct group **);
-
- int rv, rerrno;
-
- *retval = NULL;
- rv = _nss_winbind_getgrent_r(&_winbind_group,
- _winbind_groupbuf, sizeof(_winbind_groupbuf), &rerrno);
- if (rv == NS_SUCCESS)
- *retval = &_winbind_group;
- return rv;
-}
-
-int
-netbsdwinbind_getgrent_r(void *nsrv, void *nscb, va_list ap)
-{
- int *retval = va_arg(ap, int *);
- struct group *grp = va_arg(ap, struct group *);
- char *buffer = va_arg(ap, char *);
- size_t buflen = va_arg(ap, size_t);
- struct group **result = va_arg(ap, struct group **);
-
- int rv, rerrno;
-
- *result = NULL;
- rerrno = 0;
-
- rv = _nss_winbind_getgrent_r(grp, buffer, buflen, rerrno);
- if (rv == NS_SUCCESS)
- *result = grp;
- else
- *retval = rerrno;
- return rv;
-}
-
-int
-netbsdwinbind_getgrgid(void *nsrv, void *nscb, va_list ap)
-{
- struct group **retval = va_arg(ap, struct group **);
- gid_t gid = va_arg(ap, gid_t);
-
- int rv, rerrno;
-
- *retval = NULL;
- rv = _nss_winbind_getgrgid_r(gid, &_winbind_group,
- _winbind_groupbuf, sizeof(_winbind_groupbuf), &rerrno);
- if (rv == NS_SUCCESS)
- *retval = &_winbind_group;
- return rv;
-}
-
-int
-netbsdwinbind_getgrgid_r(void *nsrv, void *nscb, va_list ap)
-{
- int *retval = va_arg(ap, int *);
- gid_t gid = va_arg(ap, gid_t);
- struct group *grp = va_arg(ap, struct group *);
- char *buffer = va_arg(ap, char *);
- size_t buflen = va_arg(ap, size_t);
- struct group **result = va_arg(ap, struct group **);
-
- int rv, rerrno;
-
- *result = NULL;
- rerrno = 0;
-
- rv = _nss_winbind_getgrgid_r(gid, grp, buffer, buflen, &rerrno);
- if (rv == NS_SUCCESS)
- *result = grp;
- else
- *retval = rerrno;
- return rv;
-}
-
-int
-netbsdwinbind_getgrnam(void *nsrv, void *nscb, va_list ap)
-{
- struct group **retval = va_arg(ap, struct group **);
- const char *name = va_arg(ap, const char *);
-
- int rv, rerrno;
-
- *retval = NULL;
- rv = _nss_winbind_getgrnam_r(name, &_winbind_group,
- _winbind_groupbuf, sizeof(_winbind_groupbuf), &rerrno);
- if (rv == NS_SUCCESS)
- *retval = &_winbind_group;
- return rv;
-}
-
-int
-netbsdwinbind_getgrnam_r(void *nsrv, void *nscb, va_list ap)
-{
- int *retval = va_arg(ap, int *);
- const char *name = va_arg(ap, const char *);
- struct group *grp = va_arg(ap, struct group *);
- char *buffer = va_arg(ap, char *);
- size_t buflen = va_arg(ap, size_t);
- struct group **result = va_arg(ap, struct group **);
-
- int rv, rerrno;
-
- *result = NULL;
- rerrno = 0;
-
- rv = _nss_winbind_getgrnam_r(name, grp, buffer, buflen, &rerrno);
- if (rv == NS_SUCCESS)
- *result = grp;
- else
- *retval = rerrno;
- return rv;
-}
-
-int
-netbsdwinbind_getgroupmembership(void *nsrv, void *nscb, va_list ap)
-{
- int *result = va_arg(ap, int *);
- const char *uname = va_arg(ap, const char *);
- gid_t agroup = va_arg(ap, gid_t);
- gid_t *groups = va_arg(ap, gid_t *);
- int maxgrp = va_arg(ap, int);
- int *groupc = va_arg(ap, int *);
-
- struct winbindd_request request;
- struct winbindd_response response;
- gid_t *wblistv;
- int wblistc, i, isdup, dupc;
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
- strncpy(request.data.username, uname,
- sizeof(request.data.username) - 1);
- i = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response);
- if (i != NSS_STATUS_SUCCESS)
- return NS_NOTFOUND;
- wblistv = (gid_t *)response.extra_data.data;
- wblistc = response.data.num_entries;
-
- for (i = 0; i < wblistc; i++) { /* add winbind gids */
- isdup = 0; /* skip duplicates */
- for (dupc = 0; dupc < MIN(maxgrp, *groupc); dupc++) {
- if (groups[dupc] == wblistv[i]) {
- isdup = 1;
- break;
- }
- }
- if (isdup)
- continue;
- if (*groupc < maxgrp) /* add this gid */
- groups[*groupc] = wblistv[i];
- else
- *result = -1;
- (*groupc)++;
- }
- SAFE_FREE(wblistv);
- return NS_NOTFOUND;
-}
-
-
-/*
- passwd functions
- ----------------
-*/
-
-static struct passwd _winbind_passwd;
-static char _winbind_passwdbuf[1024];
-
-int
-netbsdwinbind_endpwent(void *nsrv, void *nscb, va_list ap)
-{
- int rv;
-
- rv = _nss_winbind_endpwent();
- return rv;
-}
-
-int
-netbsdwinbind_setpwent(void *nsrv, void *nscb, va_list ap)
-{
- int rv;
-
- rv = _nss_winbind_setpwent();
- return rv;
-}
-
-int
-netbsdwinbind_getpwent(void *nsrv, void *nscb, va_list ap)
-{
- struct passwd **retval = va_arg(ap, struct passwd **);
-
- int rv, rerrno;
-
- *retval = NULL;
-
- rv = _nss_winbind_getpwent_r(&_winbind_passwd,
- _winbind_passwdbuf, sizeof(_winbind_passwdbuf), &rerrno);
- if (rv == NS_SUCCESS)
- *retval = &_winbind_passwd;
- return rv;
-}
-
-int
-netbsdwinbind_getpwent_r(void *nsrv, void *nscb, va_list ap)
-{
- int *retval = va_arg(ap, int *);
- struct passwd *pw = va_arg(ap, struct passwd *);
- char *buffer = va_arg(ap, char *);
- size_t buflen = va_arg(ap, size_t);
- struct passwd **result = va_arg(ap, struct passwd **);
-
- int rv, rerrno;
-
- *result = NULL;
- rerrno = 0;
-
- rv = _nss_winbind_getpwent_r(pw, buffer, buflen, rerrno);
- if (rv == NS_SUCCESS)
- *result = pw;
- else
- *retval = rerrno;
- return rv;
-}
-
-int
-netbsdwinbind_getpwnam(void *nsrv, void *nscb, va_list ap)
-{
- struct passwd **retval = va_arg(ap, struct passwd **);
- const char *name = va_arg(ap, const char *);
-
- int rv, rerrno;
-
- *retval = NULL;
- rv = _nss_winbind_getpwnam_r(name, &_winbind_passwd,
- _winbind_passwdbuf, sizeof(_winbind_passwdbuf), &rerrno);
- if (rv == NS_SUCCESS)
- *retval = &_winbind_passwd;
- return rv;
-}
-
-int
-netbsdwinbind_getpwnam_r(void *nsrv, void *nscb, va_list ap)
-{
- int *retval = va_arg(ap, int *);
- const char *name = va_arg(ap, const char *);
- struct passwd *pw = va_arg(ap, struct passwd *);
- char *buffer = va_arg(ap, char *);
- size_t buflen = va_arg(ap, size_t);
- struct passwd **result = va_arg(ap, struct passwd **);
-
- int rv, rerrno;
-
- *result = NULL;
- rerrno = 0;
-
- rv = _nss_winbind_getpwnam_r(name, pw, buffer, buflen, &rerrno);
- if (rv == NS_SUCCESS)
- *result = pw;
- else
- *retval = rerrno;
- return rv;
-}
-
-int
-netbsdwinbind_getpwuid(void *nsrv, void *nscb, va_list ap)
-{
- struct passwd **retval = va_arg(ap, struct passwd **);
- uid_t uid = va_arg(ap, uid_t);
-
- int rv, rerrno;
-
- *retval = NULL;
- rv = _nss_winbind_getpwuid_r(uid, &_winbind_passwd,
- _winbind_passwdbuf, sizeof(_winbind_passwdbuf), &rerrno);
- if (rv == NS_SUCCESS)
- *retval = &_winbind_passwd;
- return rv;
-}
-
-int
-netbsdwinbind_getpwuid_r(void *nsrv, void *nscb, va_list ap)
-{
- int *retval = va_arg(ap, int *);
- uid_t uid = va_arg(ap, uid_t);
- struct passwd *pw = va_arg(ap, struct passwd *);
- char *buffer = va_arg(ap, char *);
- size_t buflen = va_arg(ap, size_t);
- struct passwd **result = va_arg(ap, struct passwd **);
-
- int rv, rerrno;
-
- *result = NULL;
- rerrno = 0;
-
- rv = _nss_winbind_getpwuid_r(uid, pw, buffer, buflen, &rerrno);
- if (rv == NS_SUCCESS)
- *result = pw;
- else
- *retval = rerrno;
- return rv;
-}
-
-
-/*
- nsswitch module setup
- ---------------------
-*/
-
-
-static ns_mtab winbind_methods[] = {
-
-{ NSDB_GROUP, "endgrent", netbsdwinbind_endgrent, NULL },
-{ NSDB_GROUP, "getgrent", netbsdwinbind_getgrent, NULL },
-{ NSDB_GROUP, "getgrent_r", netbsdwinbind_getgrent_r, NULL },
-{ NSDB_GROUP, "getgrgid", netbsdwinbind_getgrgid, NULL },
-{ NSDB_GROUP, "getgrgid_r", netbsdwinbind_getgrgid_r, NULL },
-{ NSDB_GROUP, "getgrnam", netbsdwinbind_getgrnam, NULL },
-{ NSDB_GROUP, "getgrnam_r", netbsdwinbind_getgrnam_r, NULL },
-{ NSDB_GROUP, "setgrent", netbsdwinbind_setgrent, NULL },
-{ NSDB_GROUP, "setgroupent", netbsdwinbind_setgrent, NULL },
-{ NSDB_GROUP, "getgroupmembership", netbsdwinbind_getgroupmembership, NULL },
-
-{ NSDB_PASSWD, "endpwent", netbsdwinbind_endpwent, NULL },
-{ NSDB_PASSWD, "getpwent", netbsdwinbind_getpwent, NULL },
-{ NSDB_PASSWD, "getpwent_r", netbsdwinbind_getpwent_r, NULL },
-{ NSDB_PASSWD, "getpwnam", netbsdwinbind_getpwnam, NULL },
-{ NSDB_PASSWD, "getpwnam_r", netbsdwinbind_getpwnam_r, NULL },
-{ NSDB_PASSWD, "getpwuid", netbsdwinbind_getpwuid, NULL },
-{ NSDB_PASSWD, "getpwuid_r", netbsdwinbind_getpwuid_r, NULL },
-{ NSDB_PASSWD, "setpassent", netbsdwinbind_setpwent, NULL },
-{ NSDB_PASSWD, "setpwent", netbsdwinbind_setpwent, NULL },
-
-};
-
-ns_mtab *
-nss_module_register(const char *source, unsigned int *mtabsize,
- nss_module_unregister_fn *unreg)
-{
- *mtabsize = sizeof(winbind_methods)/sizeof(winbind_methods[0]);
- *unreg = NULL;
- return (winbind_methods);
-}
-
-#endif /* NSS_MODULE_INTERFACE_VERSION && HAVE_GETPWENT_R */
diff --git a/source3/nsswitch/winbind_nss_netbsd.h b/source3/nsswitch/winbind_nss_netbsd.h
deleted file mode 100644
index dceb57c784..0000000000
--- a/source3/nsswitch/winbind_nss_netbsd.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- NetBSD loadable authentication module, providing identification
- routines against Samba winbind/Windows NT Domain
-
- Copyright (C) Luke Mewburn 2004-2005
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _WINBIND_NSS_NETBSD_H
-#define _WINBIND_NSS_NETBSD_H
-
-#include <nsswitch.h>
-
- /* dynamic nsswitch with "new" getpw* nsdispatch API available */
-#if defined(NSS_MODULE_INTERFACE_VERSION) && defined(HAVE_GETPWENT_R)
-
-typedef int NSS_STATUS;
-
-#define NSS_STATUS_SUCCESS NS_SUCCESS
-#define NSS_STATUS_NOTFOUND NS_NOTFOUND
-#define NSS_STATUS_UNAVAIL NS_UNAVAIL
-#define NSS_STATUS_TRYAGAIN NS_TRYAGAIN
-
-#endif /* NSS_MODULE_INTERFACE_VERSION && HAVE_GETPWENT_R */
-
-#endif /* _WINBIND_NSS_NETBSD_H */
diff --git a/source3/nsswitch/winbind_nss_solaris.c b/source3/nsswitch/winbind_nss_solaris.c
deleted file mode 100644
index 865b6ebbb0..0000000000
--- a/source3/nsswitch/winbind_nss_solaris.c
+++ /dev/null
@@ -1,654 +0,0 @@
-/*
- Solaris NSS wrapper for winbind
- - Shirish Kalele 2000
-
- Based on Luke Howard's ldap_nss module for Solaris
- */
-
-/*
- Copyright (C) 1997-2003 Luke Howard.
- This file is part of the nss_ldap library.
-
- The nss_ldap library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 3 of the
- License, or (at your option) any later version.
-
- The nss_ldap library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the nss_ldap library; see the file COPYING.LIB. If not,
- see <http://www.gnu.org/licenses/>.
-*/
-
-#undef DEVELOPER
-
-#include "winbind_client.h"
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <string.h>
-#include <pwd.h>
-#include "includes.h"
-#include <syslog.h>
-#if !defined(HPUX)
-#include <sys/syslog.h>
-#endif /*hpux*/
-
-#if defined(HAVE_NSS_COMMON_H) || defined(HPUX)
-
-#undef NSS_DEBUG
-
-#ifdef NSS_DEBUG
-#define NSS_DEBUG(str) syslog(LOG_DEBUG, "nss_winbind: %s", str);
-#else
-#define NSS_DEBUG(str) ;
-#endif
-
-#define NSS_ARGS(args) ((nss_XbyY_args_t *)args)
-
-#ifdef HPUX
-
-/*
- * HP-UX 11 has no definiton of the nss_groupsbymem structure. This
- * definition is taken from the nss_ldap project at:
- * http://www.padl.com/OSS/nss_ldap.html
- */
-
-struct nss_groupsbymem {
- const char *username;
- gid_t *gid_array;
- int maxgids;
- int force_slow_way;
- int (*str2ent)(const char *instr, int instr_len, void *ent,
- char *buffer, int buflen);
- nss_status_t (*process_cstr)(const char *instr, int instr_len,
- struct nss_groupsbymem *);
- int numgids;
-};
-
-#endif /* HPUX */
-
-#define make_pwent_str(dest, src) \
-{ \
- if((dest = get_static(buffer, buflen, strlen(src)+1)) == NULL) \
- { \
- *errnop = ERANGE; \
- NSS_DEBUG("ERANGE error"); \
- return NSS_STATUS_TRYAGAIN; \
- } \
- strcpy(dest, src); \
-}
-
-static NSS_STATUS _nss_winbind_setpwent_solwrap (nss_backend_t* be, void* args)
-{
- NSS_DEBUG("_nss_winbind_setpwent_solwrap");
- return _nss_winbind_setpwent();
-}
-
-static NSS_STATUS
-_nss_winbind_endpwent_solwrap (nss_backend_t * be, void *args)
-{
- NSS_DEBUG("_nss_winbind_endpwent_solwrap");
- return _nss_winbind_endpwent();
-}
-
-static NSS_STATUS
-_nss_winbind_getpwent_solwrap (nss_backend_t* be, void *args)
-{
- NSS_STATUS ret;
- char* buffer = NSS_ARGS(args)->buf.buffer;
- int buflen = NSS_ARGS(args)->buf.buflen;
- struct passwd* result = (struct passwd*) NSS_ARGS(args)->buf.result;
- int* errnop = &NSS_ARGS(args)->erange;
- char logmsg[80];
-
- ret = _nss_winbind_getpwent_r(result, buffer,
- buflen, errnop);
-
- if(ret == NSS_STATUS_SUCCESS)
- {
- snprintf(logmsg, 79, "_nss_winbind_getpwent_solwrap: Returning user: %s\n",
- result->pw_name);
- NSS_DEBUG(logmsg);
- NSS_ARGS(args)->returnval = (void*) result;
- } else {
- snprintf(logmsg, 79, "_nss_winbind_getpwent_solwrap: Returning error: %d.\n",ret);
- NSS_DEBUG(logmsg);
- }
-
- return ret;
-}
-
-static NSS_STATUS
-_nss_winbind_getpwnam_solwrap (nss_backend_t* be, void* args)
-{
- NSS_STATUS ret;
- struct passwd* result = (struct passwd*) NSS_ARGS(args)->buf.result;
-
- NSS_DEBUG("_nss_winbind_getpwnam_solwrap");
-
- ret = _nss_winbind_getpwnam_r (NSS_ARGS(args)->key.name,
- result,
- NSS_ARGS(args)->buf.buffer,
- NSS_ARGS(args)->buf.buflen,
- &NSS_ARGS(args)->erange);
- if(ret == NSS_STATUS_SUCCESS)
- NSS_ARGS(args)->returnval = (void*) result;
-
- return ret;
-}
-
-static NSS_STATUS
-_nss_winbind_getpwuid_solwrap(nss_backend_t* be, void* args)
-{
- NSS_STATUS ret;
- struct passwd* result = (struct passwd*) NSS_ARGS(args)->buf.result;
-
- NSS_DEBUG("_nss_winbind_getpwuid_solwrap");
- ret = _nss_winbind_getpwuid_r (NSS_ARGS(args)->key.uid,
- result,
- NSS_ARGS(args)->buf.buffer,
- NSS_ARGS(args)->buf.buflen,
- &NSS_ARGS(args)->erange);
- if(ret == NSS_STATUS_SUCCESS)
- NSS_ARGS(args)->returnval = (void*) result;
-
- return ret;
-}
-
-static NSS_STATUS _nss_winbind_passwd_destr (nss_backend_t * be, void *args)
-{
- SAFE_FREE(be);
- NSS_DEBUG("_nss_winbind_passwd_destr");
- return NSS_STATUS_SUCCESS;
-}
-
-static nss_backend_op_t passwd_ops[] =
-{
- _nss_winbind_passwd_destr,
- _nss_winbind_endpwent_solwrap, /* NSS_DBOP_ENDENT */
- _nss_winbind_setpwent_solwrap, /* NSS_DBOP_SETENT */
- _nss_winbind_getpwent_solwrap, /* NSS_DBOP_GETENT */
- _nss_winbind_getpwnam_solwrap, /* NSS_DBOP_PASSWD_BYNAME */
- _nss_winbind_getpwuid_solwrap /* NSS_DBOP_PASSWD_BYUID */
-};
-
-nss_backend_t*
-_nss_winbind_passwd_constr (const char* db_name,
- const char* src_name,
- const char* cfg_args)
-{
- nss_backend_t *be;
-
- if(!(be = SMB_MALLOC_P(nss_backend_t)) )
- return NULL;
-
- be->ops = passwd_ops;
- be->n_ops = sizeof(passwd_ops) / sizeof(nss_backend_op_t);
-
- NSS_DEBUG("Initialized nss_winbind passwd backend");
- return be;
-}
-
-/*****************************************************************
- GROUP database backend
- *****************************************************************/
-
-static NSS_STATUS _nss_winbind_setgrent_solwrap (nss_backend_t* be, void* args)
-{
- NSS_DEBUG("_nss_winbind_setgrent_solwrap");
- return _nss_winbind_setgrent();
-}
-
-static NSS_STATUS
-_nss_winbind_endgrent_solwrap (nss_backend_t * be, void *args)
-{
- NSS_DEBUG("_nss_winbind_endgrent_solwrap");
- return _nss_winbind_endgrent();
-}
-
-static NSS_STATUS
-_nss_winbind_getgrent_solwrap(nss_backend_t* be, void* args)
-{
- NSS_STATUS ret;
- char* buffer = NSS_ARGS(args)->buf.buffer;
- int buflen = NSS_ARGS(args)->buf.buflen;
- struct group* result = (struct group*) NSS_ARGS(args)->buf.result;
- int* errnop = &NSS_ARGS(args)->erange;
- char logmsg[80];
-
- ret = _nss_winbind_getgrent_r(result, buffer,
- buflen, errnop);
-
- if(ret == NSS_STATUS_SUCCESS)
- {
- snprintf(logmsg, 79, "_nss_winbind_getgrent_solwrap: Returning group: %s\n", result->gr_name);
- NSS_DEBUG(logmsg);
- NSS_ARGS(args)->returnval = (void*) result;
- } else {
- snprintf(logmsg, 79, "_nss_winbind_getgrent_solwrap: Returning error: %d.\n", ret);
- NSS_DEBUG(logmsg);
- }
-
- return ret;
-
-}
-
-static NSS_STATUS
-_nss_winbind_getgrnam_solwrap(nss_backend_t* be, void* args)
-{
- NSS_STATUS ret;
- struct group* result = (struct group*) NSS_ARGS(args)->buf.result;
-
- NSS_DEBUG("_nss_winbind_getgrnam_solwrap");
- ret = _nss_winbind_getgrnam_r(NSS_ARGS(args)->key.name,
- result,
- NSS_ARGS(args)->buf.buffer,
- NSS_ARGS(args)->buf.buflen,
- &NSS_ARGS(args)->erange);
-
- if(ret == NSS_STATUS_SUCCESS)
- NSS_ARGS(args)->returnval = (void*) result;
-
- return ret;
-}
-
-static NSS_STATUS
-_nss_winbind_getgrgid_solwrap(nss_backend_t* be, void* args)
-{
- NSS_STATUS ret;
- struct group* result = (struct group*) NSS_ARGS(args)->buf.result;
-
- NSS_DEBUG("_nss_winbind_getgrgid_solwrap");
- ret = _nss_winbind_getgrgid_r (NSS_ARGS(args)->key.gid,
- result,
- NSS_ARGS(args)->buf.buffer,
- NSS_ARGS(args)->buf.buflen,
- &NSS_ARGS(args)->erange);
-
- if(ret == NSS_STATUS_SUCCESS)
- NSS_ARGS(args)->returnval = (void*) result;
-
- return ret;
-}
-
-static NSS_STATUS
-_nss_winbind_getgroupsbymember_solwrap(nss_backend_t* be, void* args)
-{
- int errnop;
- struct nss_groupsbymem *gmem = (struct nss_groupsbymem *)args;
-
- NSS_DEBUG("_nss_winbind_getgroupsbymember");
-
- _nss_winbind_initgroups_dyn(gmem->username,
- gmem->gid_array[0], /* Primary Group */
- &gmem->numgids,
- &gmem->maxgids,
- &gmem->gid_array,
- gmem->maxgids,
- &errnop);
-
- /*
- * If the maximum number of gids have been found, return
- * SUCCESS so the switch engine will stop searching. Otherwise
- * return NOTFOUND so nsswitch will continue to get groups
- * from the remaining database backends specified in the
- * nsswitch.conf file.
- */
- return (gmem->numgids == gmem->maxgids ? NSS_STATUS_SUCCESS : NSS_STATUS_NOTFOUND);
-}
-
-static NSS_STATUS
-_nss_winbind_group_destr (nss_backend_t* be, void* args)
-{
- SAFE_FREE(be);
- NSS_DEBUG("_nss_winbind_group_destr");
- return NSS_STATUS_SUCCESS;
-}
-
-static nss_backend_op_t group_ops[] =
-{
- _nss_winbind_group_destr,
- _nss_winbind_endgrent_solwrap,
- _nss_winbind_setgrent_solwrap,
- _nss_winbind_getgrent_solwrap,
- _nss_winbind_getgrnam_solwrap,
- _nss_winbind_getgrgid_solwrap,
- _nss_winbind_getgroupsbymember_solwrap
-};
-
-nss_backend_t*
-_nss_winbind_group_constr (const char* db_name,
- const char* src_name,
- const char* cfg_args)
-{
- nss_backend_t* be;
-
- if(!(be = SMB_MALLOC_P(nss_backend_t)) )
- return NULL;
-
- be->ops = group_ops;
- be->n_ops = sizeof(group_ops) / sizeof(nss_backend_op_t);
-
- NSS_DEBUG("Initialized nss_winbind group backend");
- return be;
-}
-
-/*****************************************************************
- hosts and ipnodes backend
- *****************************************************************/
-#if defined(SUNOS5) /* not compatible with HP-UX */
-
-/* this parser is shared between get*byname and get*byaddr, as key type
- in request is stored in different locations, I had to provide the
- address family as an argument, caller must free the winbind response. */
-
-static NSS_STATUS
-parse_response(int af, nss_XbyY_args_t* argp, struct winbindd_response *response)
-{
- struct hostent *he = (struct hostent *)argp->buf.result;
- char *buffer = argp->buf.buffer;
- int buflen = argp->buf.buflen;
- NSS_STATUS ret;
-
- char *p, *data;
- int addrcount = 0;
- int len = 0;
- struct in_addr *addrp;
-#if defined(AF_INET6)
- struct in6_addr *addrp6;
-#endif
- int i;
-
- /* response is tab separated list of ip addresses with hostname
- and newline at the end. so at first we will strip newline
- then construct list of addresses for hostent.
- */
- p = strchr(response->data.winsresp, '\n');
- if(p) *p = '\0';
- else {/* it must be broken */
- argp->h_errno = NO_DATA;
- return NSS_STATUS_UNAVAIL;
- }
-
- for(; p != response->data.winsresp; p--) {
- if(*p == '\t') addrcount++;
- }
-
- if(addrcount == 0) {/* it must be broken */
- argp->h_errno = NO_DATA;
- return NSS_STATUS_UNAVAIL;
- }
-
- /* allocate space for addresses and h_addr_list */
- he->h_addrtype = af;
- if( he->h_addrtype == AF_INET) {
- he->h_length = sizeof(struct in_addr);
- addrp = (struct in_addr *)ROUND_DOWN(buffer + buflen,
- sizeof(struct in_addr));
- addrp -= addrcount;
- he->h_addr_list = (char **)ROUND_DOWN(addrp, sizeof (char*));
- he->h_addr_list -= addrcount+1;
- }
-#if defined(AF_INET6)
- else {
- he->h_length = sizeof(struct in6_addr);
- addrp6 = (struct in6_addr *)ROUND_DOWN(buffer + buflen,
- sizeof(struct in6_addr));
- addrp6 -= addrcount;
- he->h_addr_list = (char **)ROUND_DOWN(addrp6, sizeof (char*));
- he->h_addr_list -= addrcount+1;
- }
-#endif
-
- /* buffer too small?! */
- if((char *)he->h_addr_list < buffer ) {
- argp->erange = 1;
- return NSS_STR_PARSE_ERANGE;
- }
-
- data = response->data.winsresp;
- for( i = 0; i < addrcount; i++) {
- p = strchr(data, '\t');
- if(p == NULL) break; /* just in case... */
-
- *p = '\0'; /* terminate the string */
- if(he->h_addrtype == AF_INET) {
- he->h_addr_list[i] = (char *)&addrp[i];
- if ((addrp[i].s_addr = inet_addr(data)) == -1) {
- argp->erange = 1;
- return NSS_STR_PARSE_ERANGE;
- }
- }
-#if defined(AF_INET6)
- else {
- he->h_addr_list[i] = (char *)&addrp6[i];
- if (strchr(data, ':') != 0) {
- if (inet_pton(AF_INET6, data, &addrp6[i]) != 1) {
- argp->erange = 1;
- return NSS_STR_PARSE_ERANGE;
- }
- } else {
- struct in_addr in4;
- if ((in4.s_addr = inet_addr(data)) == -1) {
- argp->erange = 1;
- return NSS_STR_PARSE_ERANGE;
- }
- IN6_INADDR_TO_V4MAPPED(&in4, &addrp6[i]);
- }
- }
-#endif
- data = p+1;
- }
-
- he->h_addr_list[i] = (char *)NULL;
-
- len = strlen(data);
- if(len > he->h_addr_list - (char**)argp->buf.buffer) {
- argp->erange = 1;
- return NSS_STR_PARSE_ERANGE;
- }
-
- /* this is a bit overkill to use _nss_netdb_aliases here since
- there seems to be no aliases but it will create all data for us */
- he->h_aliases = _nss_netdb_aliases(data, len, buffer,
- ((char*) he->h_addr_list) - buffer);
- if(he->h_aliases == NULL) {
- argp->erange = 1;
- ret = NSS_STR_PARSE_ERANGE;
- } else {
- he->h_name = he->h_aliases[0];
- he->h_aliases++;
- ret = NSS_STR_PARSE_SUCCESS;
- }
-
- argp->returnval = (void*)he;
- return ret;
-}
-
-static NSS_STATUS
-_nss_winbind_ipnodes_getbyname(nss_backend_t* be, void *args)
-{
- nss_XbyY_args_t *argp = (nss_XbyY_args_t*) args;
- struct winbindd_response response;
- struct winbindd_request request;
- NSS_STATUS ret;
- int af;
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- /* I assume there that AI_ADDRCONFIG cases are handled in nss
- frontend code, at least it seems done so in solaris...
-
- we will give NO_DATA for pure IPv6; IPv4 will be returned for
- AF_INET or for AF_INET6 and AI_ALL|AI_V4MAPPED we have to map
- IPv4 to IPv6.
- */
-#if defined(AF_INET6)
-#ifdef HAVE_NSS_XBYY_KEY_IPNODE
- af = argp->key.ipnode.af_family;
- if(af == AF_INET6 && argp->key.ipnode.flags == 0) {
- argp->h_errno = NO_DATA;
- return NSS_STATUS_UNAVAIL;
- }
-#else
- /* I'm not that sure if this is correct, but... */
- af = AF_INET6;
-#endif
-#endif
-
- strncpy(request.data.winsreq, argp->key.name, sizeof(request.data.winsreq) - 1);
- request.data.winsreq[sizeof(request.data.winsreq) - 1] = '\0';
-
- if( (ret = winbindd_request_response(WINBINDD_WINS_BYNAME, &request, &response))
- == NSS_STATUS_SUCCESS ) {
- ret = parse_response(af, argp, &response);
- }
-
- winbindd_free_response(&response);
- return ret;
-}
-
-static NSS_STATUS
-_nss_winbind_hosts_getbyname(nss_backend_t* be, void *args)
-{
- nss_XbyY_args_t *argp = (nss_XbyY_args_t*) args;
- struct winbindd_response response;
- struct winbindd_request request;
- NSS_STATUS ret;
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
- strncpy(request.data.winsreq, argp->key.name, sizeof(request.data.winsreq) - 1);
- request.data.winsreq[sizeof(request.data.winsreq) - 1] = '\0';
-
- if( (ret = winbindd_request_response(WINBINDD_WINS_BYNAME, &request, &response))
- == NSS_STATUS_SUCCESS ) {
- ret = parse_response(AF_INET, argp, &response);
- }
-
- winbindd_free_response(&response);
- return ret;
-}
-
-static NSS_STATUS
-_nss_winbind_hosts_getbyaddr(nss_backend_t* be, void *args)
-{
- NSS_STATUS ret;
- struct winbindd_response response;
- struct winbindd_request request;
- nss_XbyY_args_t *argp = (nss_XbyY_args_t *)args;
- const char *p;
-
- ZERO_STRUCT(response);
- ZERO_STRUCT(request);
-
-#if defined(AF_INET6)
- /* winbindd currently does not resolve IPv6 */
- if(argp->key.hostaddr.type == AF_INET6) {
- argp->h_errno = NO_DATA;
- return NSS_STATUS_UNAVAIL;
- }
-
- p = inet_ntop(argp->key.hostaddr.type, argp->key.hostaddr.addr,
- request.data.winsreq, sizeof request.data.winsreq);
-#else
- snprintf(request.data.winsreq, sizeof request.data.winsreq,
- "%u.%u.%u.%u",
- ((unsigned char *)argp->key.hostaddr.addr)[0],
- ((unsigned char *)argp->key.hostaddr.addr)[1],
- ((unsigned char *)argp->key.hostaddr.addr)[2],
- ((unsigned char *)argp->key.hostaddr.addr)[3]);
-#endif
-
- ret = winbindd_request_response(WINBINDD_WINS_BYIP, &request, &response);
-
- if( ret == NSS_STATUS_SUCCESS) {
- parse_response(argp->key.hostaddr.type, argp, &response);
- }
- winbindd_free_response(&response);
- return ret;
-}
-
-/* winbind does not provide setent, getent, endent for wins */
-static NSS_STATUS
-_nss_winbind_common_endent(nss_backend_t* be, void *args)
-{
- return (NSS_STATUS_UNAVAIL);
-}
-
-static NSS_STATUS
-_nss_winbind_common_setent(nss_backend_t* be, void *args)
-{
- return (NSS_STATUS_UNAVAIL);
-}
-
-static NSS_STATUS
-_nss_winbind_common_getent(nss_backend_t* be, void *args)
-{
- return (NSS_STATUS_UNAVAIL);
-}
-
-static nss_backend_t*
-_nss_winbind_common_constr (nss_backend_op_t ops[], int n_ops)
-{
- nss_backend_t* be;
-
- if(!(be = SMB_MALLOC_P(nss_backend_t)) )
- return NULL;
-
- be->ops = ops;
- be->n_ops = n_ops;
-
- return be;
-}
-
-static NSS_STATUS
-_nss_winbind_common_destr (nss_backend_t* be, void* args)
-{
- SAFE_FREE(be);
- return NSS_STATUS_SUCCESS;
-}
-
-static nss_backend_op_t ipnodes_ops[] = {
- _nss_winbind_common_destr,
- _nss_winbind_common_endent,
- _nss_winbind_common_setent,
- _nss_winbind_common_getent,
- _nss_winbind_ipnodes_getbyname,
- _nss_winbind_hosts_getbyaddr,
-};
-
-nss_backend_t *
-_nss_winbind_ipnodes_constr(dummy1, dummy2, dummy3)
- const char *dummy1, *dummy2, *dummy3;
-{
- return (_nss_winbind_common_constr(ipnodes_ops,
- sizeof (ipnodes_ops) / sizeof (ipnodes_ops[0])));
-}
-
-static nss_backend_op_t host_ops[] = {
- _nss_winbind_common_destr,
- _nss_winbind_common_endent,
- _nss_winbind_common_setent,
- _nss_winbind_common_getent,
- _nss_winbind_hosts_getbyname,
- _nss_winbind_hosts_getbyaddr,
-};
-
-nss_backend_t *
-_nss_winbind_hosts_constr(dummy1, dummy2, dummy3)
- const char *dummy1, *dummy2, *dummy3;
-{
- return (_nss_winbind_common_constr(host_ops,
- sizeof (host_ops) / sizeof (host_ops[0])));
-}
-
-#endif /* defined(SUNOS5) */
-#endif /* defined(HAVE_NSS_COMMON_H) || defined(HPUX) */
diff --git a/source3/nsswitch/winbind_nss_solaris.h b/source3/nsswitch/winbind_nss_solaris.h
deleted file mode 100644
index 84062dbab4..0000000000
--- a/source3/nsswitch/winbind_nss_solaris.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon for ntdom nss module
-
- Copyright (C) Tim Potter 2000
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _WINBIND_NSS_SOLARIS_H
-#define _WINBIND_NSS_SOLARIS_H
-
-/* Solaris has a broken nss_common header file containing C++ reserved names. */
-#ifndef __cplusplus
-#undef class
-#undef private
-#undef public
-#undef protected
-#undef template
-#undef this
-#undef new
-#undef delete
-#undef friend
-#endif
-
-#include <nss_common.h>
-
-#ifndef __cplusplus
-#define class #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#define private #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#define public #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#define protected #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#define template #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#define this #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#define new #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#define delete #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#define friend #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#endif
-
-#include <nss_dbdefs.h>
-#include <nsswitch.h>
-
-typedef nss_status_t NSS_STATUS;
-
-#define NSS_STATUS_SUCCESS NSS_SUCCESS
-#define NSS_STATUS_NOTFOUND NSS_NOTFOUND
-#define NSS_STATUS_UNAVAIL NSS_UNAVAIL
-#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN
-
-/* The solaris winbind is implemented as a wrapper around the linux
- version. */
-
-NSS_STATUS _nss_winbind_setpwent(void);
-NSS_STATUS _nss_winbind_endpwent(void);
-NSS_STATUS _nss_winbind_getpwent_r(struct passwd* result, char* buffer,
- size_t buflen, int* errnop);
-NSS_STATUS _nss_winbind_getpwuid_r(uid_t, struct passwd*, char* buffer,
- size_t buflen, int* errnop);
-NSS_STATUS _nss_winbind_getpwnam_r(const char* name, struct passwd* result,
- char* buffer, size_t buflen, int* errnop);
-
-NSS_STATUS _nss_winbind_setgrent(void);
-NSS_STATUS _nss_winbind_endgrent(void);
-NSS_STATUS _nss_winbind_getgrent_r(struct group* result, char* buffer,
- size_t buflen, int* errnop);
-NSS_STATUS _nss_winbind_getgrnam_r(const char *name,
- struct group *result, char *buffer,
- size_t buflen, int *errnop);
-NSS_STATUS _nss_winbind_getgrgid_r(gid_t gid,
- struct group *result, char *buffer,
- size_t buflen, int *errnop);
-
-#endif /* _WINBIND_NSS_SOLARIS_H */
diff --git a/source3/nsswitch/winbind_struct_protocol.h b/source3/nsswitch/winbind_struct_protocol.h
deleted file mode 100644
index 36873f2096..0000000000
--- a/source3/nsswitch/winbind_struct_protocol.h
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon for ntdom nss module
-
- Copyright (C) Tim Potter 2000
- Copyright (C) Gerald Carter 2006
-
- You are free to use this interface definition in any way you see
- fit, including without restriction, using this header in your own
- products. You do not need to give any attribution.
-*/
-
-#ifndef SAFE_FREE
-#define SAFE_FREE(x) do { if(x) {free(x); x=NULL;} } while(0)
-#endif
-
-#ifndef _WINBINDD_NTDOM_H
-#define _WINBINDD_NTDOM_H
-
-#define WINBINDD_SOCKET_NAME "pipe" /* Name of PF_UNIX socket */
-
-/* Let the build environment override the public winbindd socket location. This
- * is needed for launchd support -- jpeach.
- */
-#ifndef WINBINDD_SOCKET_DIR
-#define WINBINDD_SOCKET_DIR "/tmp/.winbindd" /* Name of PF_UNIX dir */
-#endif
-
-/*
- * when compiled with socket_wrapper support
- * the location of the WINBINDD_SOCKET_DIR
- * can be overwritten via an environment variable
- */
-#define WINBINDD_SOCKET_DIR_ENVVAR "WINBINDD_SOCKET_DIR"
-
-#define WINBINDD_PRIV_SOCKET_SUBDIR "winbindd_privileged" /* name of subdirectory of lp_lockdir() to hold the 'privileged' pipe */
-#define WINBINDD_DOMAIN_ENV "WINBINDD_DOMAIN" /* Environment variables */
-#define WINBINDD_DONT_ENV "_NO_WINBINDD"
-#define WINBINDD_LOCATOR_KDC_ADDRESS "WINBINDD_LOCATOR_KDC_ADDRESS"
-
-/* Update this when you change the interface. */
-
-/* Version 20: added WINBINDD_REMOVE_MAPPING command */
-
-#define WINBIND_INTERFACE_VERSION 20
-
-/* Have to deal with time_t being 4 or 8 bytes due to structure alignment.
- On a 64bit Linux box, we have to support a constant structure size
- between /lib/libnss_winbind.so.2 and /li64/libnss_winbind.so.2.
- The easiest way to do this is to always use 8byte values for time_t. */
-
-#define SMB_TIME_T int64_t
-
-/* Socket commands */
-
-enum winbindd_cmd {
-
- WINBINDD_INTERFACE_VERSION, /* Always a well known value */
-
- /* Get users and groups */
-
- WINBINDD_GETPWNAM,
- WINBINDD_GETPWUID,
- WINBINDD_GETGRNAM,
- WINBINDD_GETGRGID,
- WINBINDD_GETGROUPS,
-
- /* Enumerate users and groups */
-
- WINBINDD_SETPWENT,
- WINBINDD_ENDPWENT,
- WINBINDD_GETPWENT,
- WINBINDD_SETGRENT,
- WINBINDD_ENDGRENT,
- WINBINDD_GETGRENT,
-
- /* PAM authenticate and password change */
-
- WINBINDD_PAM_AUTH,
- WINBINDD_PAM_AUTH_CRAP,
- WINBINDD_PAM_CHAUTHTOK,
- WINBINDD_PAM_LOGOFF,
- WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP,
-
- /* List various things */
-
- WINBINDD_LIST_USERS, /* List w/o rid->id mapping */
- WINBINDD_LIST_GROUPS, /* Ditto */
- WINBINDD_LIST_TRUSTDOM,
-
- /* SID conversion */
-
- WINBINDD_LOOKUPSID,
- WINBINDD_LOOKUPNAME,
- WINBINDD_LOOKUPRIDS,
-
- /* Lookup functions */
-
- WINBINDD_SID_TO_UID,
- WINBINDD_SID_TO_GID,
- WINBINDD_SIDS_TO_XIDS,
- WINBINDD_UID_TO_SID,
- WINBINDD_GID_TO_SID,
-
- WINBINDD_ALLOCATE_UID,
- WINBINDD_ALLOCATE_GID,
- WINBINDD_SET_MAPPING,
- WINBINDD_REMOVE_MAPPING,
- WINBINDD_SET_HWM,
-
- /* Miscellaneous other stuff */
-
- WINBINDD_CHECK_MACHACC, /* Check machine account pw works */
- WINBINDD_PING, /* Just tell me winbind is running */
- WINBINDD_INFO, /* Various bit of info. Currently just tidbits */
- WINBINDD_DOMAIN_NAME, /* The domain this winbind server is a member of (lp_workgroup()) */
-
- WINBINDD_DOMAIN_INFO, /* Most of what we know from
- struct winbindd_domain */
- WINBINDD_GETDCNAME, /* Issue a GetDCName Request */
- WINBINDD_DSGETDCNAME, /* Issue a DsGetDCName Request */
-
- WINBINDD_SHOW_SEQUENCE, /* display sequence numbers of domains */
-
- /* WINS commands */
-
- WINBINDD_WINS_BYIP,
- WINBINDD_WINS_BYNAME,
-
- /* this is like GETGRENT but gives an empty group list */
- WINBINDD_GETGRLST,
-
- WINBINDD_NETBIOS_NAME, /* The netbios name of the server */
-
- /* find the location of our privileged pipe */
- WINBINDD_PRIV_PIPE_DIR,
-
- /* return a list of group sids for a user sid */
- WINBINDD_GETUSERSIDS,
-
- /* Various group queries */
- WINBINDD_GETUSERDOMGROUPS,
-
- /* Initialize connection in a child */
- WINBINDD_INIT_CONNECTION,
-
- /* Blocking calls that are not allowed on the main winbind pipe, only
- * between parent and children */
- WINBINDD_DUAL_SID2UID,
- WINBINDD_DUAL_SID2GID,
- WINBINDD_DUAL_SIDS2XIDS,
- WINBINDD_DUAL_UID2SID,
- WINBINDD_DUAL_GID2SID,
- WINBINDD_DUAL_SET_MAPPING,
- WINBINDD_DUAL_REMOVE_MAPPING,
- WINBINDD_DUAL_SET_HWM,
-
- /* Wrapper around possibly blocking unix nss calls */
- WINBINDD_DUAL_USERINFO,
- WINBINDD_DUAL_GETSIDALIASES,
-
- /* Complete the challenge phase of the NTLM authentication
- protocol using cached password. */
- WINBINDD_CCACHE_NTLMAUTH,
-
- WINBINDD_NUM_CMDS
-};
-
-typedef struct winbindd_pw {
- fstring pw_name;
- fstring pw_passwd;
- uid_t pw_uid;
- gid_t pw_gid;
- fstring pw_gecos;
- fstring pw_dir;
- fstring pw_shell;
-} WINBINDD_PW;
-
-
-typedef struct winbindd_gr {
- fstring gr_name;
- fstring gr_passwd;
- gid_t gr_gid;
- uint32_t num_gr_mem;
- uint32_t gr_mem_ofs; /* offset to group membership */
-} WINBINDD_GR;
-
-/* PAM specific request flags */
-#define WBFLAG_PAM_INFO3_NDR 0x00000001
-#define WBFLAG_PAM_INFO3_TEXT 0x00000002
-#define WBFLAG_PAM_USER_SESSION_KEY 0x00000004
-#define WBFLAG_PAM_LMKEY 0x00000008
-#define WBFLAG_PAM_CONTACT_TRUSTDOM 0x00000010
-#define WBFLAG_PAM_UNIX_NAME 0x00000080
-#define WBFLAG_PAM_AFS_TOKEN 0x00000100
-#define WBFLAG_PAM_NT_STATUS_SQUASH 0x00000200
-#define WBFLAG_PAM_KRB5 0x00001000
-#define WBFLAG_PAM_FALLBACK_AFTER_KRB5 0x00002000
-#define WBFLAG_PAM_CACHED_LOGIN 0x00004000
-#define WBFLAG_PAM_GET_PWD_POLICY 0x00008000
-
-/* generic request flags */
-#define WBFLAG_QUERY_ONLY 0x00000020 /* not used */
-/* This is a flag that can only be sent from parent to child */
-#define WBFLAG_IS_PRIVILEGED 0x00000400 /* not used */
-/* Flag to say this is a winbindd internal send - don't recurse. */
-#define WBFLAG_RECURSE 0x00000800
-/* Flag to tell winbind the NTLMv2 blob is too big for the struct and is in the
- * extra_data field */
-#define WBFLAG_BIG_NTLMV2_BLOB 0x00010000
-
-#define WINBINDD_MAX_EXTRA_DATA (128*1024)
-
-/* Winbind request structure */
-
-/*******************************************************************************
- * This structure MUST be the same size in the 32bit and 64bit builds
- * for compatibility between /lib64/libnss_winbind.so and /lib/libnss_winbind.so
- *
- * DO NOT CHANGE THIS STRUCTURE WITHOUT TESTING THE 32BIT NSS LIB AGAINST
- * A 64BIT WINBINDD --jerry
- ******************************************************************************/
-
-struct winbindd_request {
- uint32_t length;
- enum winbindd_cmd cmd; /* Winbindd command to execute */
- enum winbindd_cmd original_cmd; /* Original Winbindd command
- issued to parent process */
- pid_t pid; /* pid of calling process */
- uint32_t wb_flags; /* generic flags */
- uint32_t flags; /* flags relevant *only* to a given request */
- fstring domain_name; /* name of domain for which the request applies */
-
- union {
- fstring winsreq; /* WINS request */
- fstring username; /* getpwnam */
- fstring groupname; /* getgrnam */
- uid_t uid; /* getpwuid, uid_to_sid */
- gid_t gid; /* getgrgid, gid_to_sid */
- struct {
- /* We deliberatedly don't split into domain/user to
- avoid having the client know what the separator
- character is. */
- fstring user;
- fstring pass;
- char require_membership_of_sid[1024];
- fstring krb5_cc_type;
- uid_t uid;
- } auth; /* pam_winbind auth module */
- struct {
- uint8_t chal[8];
- uint32_t logon_parameters;
- fstring user;
- fstring domain;
- fstring lm_resp;
- uint32_t lm_resp_len;
- fstring nt_resp;
- uint32_t nt_resp_len;
- fstring workstation;
- fstring require_membership_of_sid;
- } auth_crap;
- struct {
- fstring user;
- fstring oldpass;
- fstring newpass;
- } chauthtok; /* pam_winbind passwd module */
- struct {
- fstring user;
- fstring domain;
- uint8_t new_nt_pswd[516];
- uint16_t new_nt_pswd_len;
- uint8_t old_nt_hash_enc[16];
- uint16_t old_nt_hash_enc_len;
- uint8_t new_lm_pswd[516];
- uint16_t new_lm_pswd_len;
- uint8_t old_lm_hash_enc[16];
- uint16_t old_lm_hash_enc_len;
- } chng_pswd_auth_crap;/* pam_winbind passwd module */
- struct {
- fstring user;
- fstring krb5ccname;
- uid_t uid;
- } logoff; /* pam_winbind session module */
- fstring sid; /* lookupsid, sid_to_[ug]id */
- struct {
- fstring dom_name; /* lookupname */
- fstring name;
- } name;
- uint32_t num_entries; /* getpwent, getgrent */
- struct {
- fstring username;
- fstring groupname;
- } acct_mgt;
- struct {
- bool is_primary;
- fstring dcname;
- } init_conn;
- struct {
- fstring sid;
- fstring name;
- } dual_sid2id;
- struct {
- fstring sid;
- uint32_t type;
- uint32_t id;
- } dual_idmapset;
- bool list_all_domains;
-
- struct {
- uid_t uid;
- fstring user;
- /* the effective uid of the client, must be the uid for 'user'.
- This is checked by the main daemon, trusted by children. */
- /* if the blobs are length zero, then this doesn't
- produce an actual challenge response. It merely
- succeeds if there are cached credentials available
- that could be used. */
- uint32_t initial_blob_len; /* blobs in extra_data */
- uint32_t challenge_blob_len;
- } ccache_ntlm_auth;
- struct {
- fstring domain_name;
- fstring domain_guid;
- fstring site_name;
- uint32_t flags;
- } dsgetdcname;
-
- /* padding -- needed to fix alignment between 32bit and 64bit libs.
- The size is the sizeof the union without the padding aligned on
- an 8 byte boundary. --jerry */
-
- char padding[1800];
- } data;
- union {
- SMB_TIME_T padding;
- char *data;
- } extra_data;
- uint32_t extra_len;
- char null_term;
-};
-
-/* Response values */
-
-enum winbindd_result {
- WINBINDD_ERROR,
- WINBINDD_PENDING,
- WINBINDD_OK
-};
-
-/* Winbind response structure */
-
-/*******************************************************************************
- * This structure MUST be the same size in the 32bit and 64bit builds
- * for compatibility between /lib64/libnss_winbind.so and /lib/libnss_winbind.so
- *
- * DO NOT CHANGE THIS STRUCTURE WITHOUT TESTING THE 32BIT NSS LIB AGAINST
- * A 64BIT WINBINDD --jerry
- ******************************************************************************/
-
-struct winbindd_response {
-
- /* Header information */
-
- uint32_t length; /* Length of response */
- enum winbindd_result result; /* Result code */
-
- /* Fixed length return data */
-
- union {
- int interface_version; /* Try to ensure this is always in the same spot... */
-
- fstring winsresp; /* WINS response */
-
- /* getpwnam, getpwuid */
-
- struct winbindd_pw pw;
-
- /* getgrnam, getgrgid */
-
- struct winbindd_gr gr;
-
- uint32_t num_entries; /* getpwent, getgrent */
- struct winbindd_sid {
- fstring sid; /* lookupname, [ug]id_to_sid */
- int type;
- } sid;
- struct winbindd_name {
- fstring dom_name; /* lookupsid */
- fstring name;
- int type;
- } name;
- uid_t uid; /* sid_to_uid */
- gid_t gid; /* sid_to_gid */
- struct winbindd_info {
- char winbind_separator;
- fstring samba_version;
- } info;
- fstring domain_name;
- fstring netbios_name;
- fstring dc_name;
-
- struct auth_reply {
- uint32_t nt_status;
- fstring nt_status_string;
- fstring error_string;
- int pam_error;
- char user_session_key[16];
- char first_8_lm_hash[8];
- fstring krb5ccname;
- uint32_t reject_reason;
- uint32_t padding;
- struct policy_settings {
- uint32_t min_length_password;
- uint32_t password_history;
- uint32_t password_properties;
- uint32_t padding;
- SMB_TIME_T expire;
- SMB_TIME_T min_passwordage;
- } policy;
- struct info3_text {
- SMB_TIME_T logon_time;
- SMB_TIME_T logoff_time;
- SMB_TIME_T kickoff_time;
- SMB_TIME_T pass_last_set_time;
- SMB_TIME_T pass_can_change_time;
- SMB_TIME_T pass_must_change_time;
- uint32_t logon_count;
- uint32_t bad_pw_count;
- uint32_t user_rid;
- uint32_t group_rid;
- uint32_t num_groups;
- uint32_t user_flgs;
- uint32_t acct_flags;
- uint32_t num_other_sids;
- fstring dom_sid;
- fstring user_name;
- fstring full_name;
- fstring logon_script;
- fstring profile_path;
- fstring home_dir;
- fstring dir_drive;
- fstring logon_srv;
- fstring logon_dom;
- } info3;
- fstring unix_username;
- } auth;
- struct {
- fstring name;
- fstring alt_name;
- fstring sid;
- bool native_mode;
- bool active_directory;
- bool primary;
- } domain_info;
- uint32_t sequence_number;
- struct {
- fstring acct_name;
- fstring full_name;
- fstring homedir;
- fstring shell;
- uint32_t primary_gid;
- uint32_t group_rid;
- } user_info;
- struct {
- uint32_t auth_blob_len; /* blob in extra_data */
- } ccache_ntlm_auth;
- struct {
- fstring dc_unc;
- fstring dc_address;
- uint32_t dc_address_type;
- fstring domain_guid;
- fstring domain_name;
- fstring forest_name;
- uint32_t dc_flags;
- fstring dc_site_name;
- fstring client_site_name;
- } dsgetdcname;
- } data;
-
- /* Variable length return data */
-
- union {
- SMB_TIME_T padding;
- void *data;
- } extra_data;
-};
-
-struct WINBINDD_MEMORY_CREDS {
- struct WINBINDD_MEMORY_CREDS *next, *prev;
- const char *username; /* lookup key. */
- uid_t uid;
- int ref_count;
- size_t len;
- uint8_t *nt_hash; /* Base pointer for the following 2 */
- uint8_t *lm_hash;
- char *pass;
-};
-
-struct WINBINDD_CCACHE_ENTRY {
- struct WINBINDD_CCACHE_ENTRY *next, *prev;
- const char *principal_name;
- const char *ccname;
- const char *service;
- const char *username;
- const char *realm;
- struct WINBINDD_MEMORY_CREDS *cred_ptr;
- int ref_count;
- uid_t uid;
- time_t create_time;
- time_t renew_until;
- time_t refresh_time;
- struct timed_event *event;
-};
-
-#endif
diff --git a/source3/nsswitch/wins.c b/source3/nsswitch/wins.c
deleted file mode 100644
index e028eb8cf2..0000000000
--- a/source3/nsswitch/wins.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- a WINS nsswitch module
- Copyright (C) Andrew Tridgell 1999
-
- 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 "includes.h"
-#ifdef HAVE_NS_API_H
-
-#include <ns_daemon.h>
-#endif
-
-#if HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
-
-#if HAVE_PTHREAD
-static pthread_mutex_t wins_nss_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif
-
-#ifndef INADDRSZ
-#define INADDRSZ 4
-#endif
-
-static int initialised;
-
-extern bool AllowDebugChange;
-
-NSS_STATUS _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he,
- char *buffer, size_t buflen, int *h_errnop);
-NSS_STATUS _nss_wins_gethostbyname2_r(const char *name, int af, struct hostent *he,
- char *buffer, size_t buflen, int *h_errnop);
-
-/* Use our own create socket code so we don't recurse.... */
-
-static int wins_lookup_open_socket_in(void)
-{
- struct sockaddr_in sock;
- int val=1;
- int res;
-
- memset((char *)&sock,'\0',sizeof(sock));
-
-#ifdef HAVE_SOCK_SIN_LEN
- sock.sin_len = sizeof(sock);
-#endif
- sock.sin_port = 0;
- sock.sin_family = AF_INET;
- sock.sin_addr.s_addr = interpret_addr("0.0.0.0");
- res = socket(AF_INET, SOCK_DGRAM, 0);
- if (res == -1)
- return -1;
-
- if (setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)) != 0) {
- close(res);
- return -1;
- }
-#ifdef SO_REUSEPORT
- if (setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) != 0) {
- close(res);
- return -1;
- }
-#endif /* SO_REUSEPORT */
-
- /* now we've got a socket - we need to bind it */
-
- if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) {
- close(res);
- return(-1);
- }
-
- set_socket_options(res,"SO_BROADCAST");
-
- return res;
-}
-
-
-static void nss_wins_init(void)
-{
- initialised = 1;
- DEBUGLEVEL = 0;
- AllowDebugChange = False;
-
- TimeInit();
- setup_logging("nss_wins",False);
- load_case_tables();
- lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
- load_interfaces();
-}
-
-static struct in_addr *lookup_byname_backend(const char *name, int *count)
-{
- int fd = -1;
- struct ip_service *address = NULL;
- struct in_addr *ret = NULL;
- int j, flags = 0;
-
- if (!initialised) {
- nss_wins_init();
- }
-
- *count = 0;
-
- /* always try with wins first */
- if (NT_STATUS_IS_OK(resolve_wins(name,0x00,&address,count))) {
- if ( (ret = SMB_MALLOC_P(struct in_addr)) == NULL ) {
- free( address );
- return NULL;
- }
- if (address[0].ss.ss_family != AF_INET) {
- free(address);
- free(ret);
- return NULL;
- }
- *ret = ((struct sockaddr_in *)&address[0].ss)->sin_addr;
- free( address );
- return ret;
- }
-
- fd = wins_lookup_open_socket_in();
- if (fd == -1) {
- return NULL;
- }
-
- /* uggh, we have to broadcast to each interface in turn */
- for (j=iface_count() - 1;j >= 0;j--) {
- const struct in_addr *bcast = iface_n_bcast_v4(j);
- struct sockaddr_storage ss;
- struct sockaddr_storage *pss;
- if (!bcast) {
- continue;
- }
- in_addr_to_sockaddr_storage(&ss, *bcast);
- pss = name_query(fd,name,0x00,True,True,&ss,count, &flags, NULL);
- if (pss) {
- if ((ret = SMB_MALLOC_P(struct in_addr)) == NULL) {
- return NULL;
- }
- *ret = ((struct sockaddr_in *)pss)->sin_addr;
- break;
- }
- }
-
- close(fd);
- return ret;
-}
-
-#ifdef HAVE_NS_API_H
-
-static NODE_STATUS_STRUCT *lookup_byaddr_backend(char *addr, int *count)
-{
- int fd;
- struct sockaddr_storage ss;
- struct nmb_name nname;
- NODE_STATUS_STRUCT *status;
-
- if (!initialised) {
- nss_wins_init();
- }
-
- fd = wins_lookup_open_socket_in();
- if (fd == -1)
- return NULL;
-
- make_nmb_name(&nname, "*", 0);
- if (!interpret_string_addr(&ss, addr, AI_NUMERICHOST)) {
- return NULL;
- }
- status = node_status_query(fd, &nname, &ss, count, NULL);
-
- close(fd);
- return status;
-}
-
-/* IRIX version */
-
-int init(void)
-{
- nsd_logprintf(NSD_LOG_MIN, "entering init (wins)\n");
- nss_wins_init();
- return NSD_OK;
-}
-
-int lookup(nsd_file_t *rq)
-{
- char *map;
- char *key;
- char *addr;
- struct in_addr *ip_list;
- NODE_STATUS_STRUCT *status;
- int i, count, len, size;
- char response[1024];
- bool found = False;
-
- nsd_logprintf(NSD_LOG_MIN, "entering lookup (wins)\n");
- if (! rq)
- return NSD_ERROR;
-
- map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0);
- if (! map) {
- rq->f_status = NS_FATAL;
- return NSD_ERROR;
- }
-
- key = nsd_attr_fetch_string(rq->f_attrs, "key", (char*)0);
- if (! key || ! *key) {
- rq->f_status = NS_FATAL;
- return NSD_ERROR;
- }
-
- response[0] = '\0';
- len = sizeof(response) - 2;
-
- /*
- * response needs to be a string of the following format
- * ip_address[ ip_address]*\tname[ alias]*
- */
- if (StrCaseCmp(map,"hosts.byaddr") == 0) {
- if ( status = lookup_byaddr_backend(key, &count)) {
- size = strlen(key) + 1;
- if (size > len) {
- free(status);
- return NSD_ERROR;
- }
- len -= size;
- strncat(response,key,size);
- strncat(response,"\t",1);
- for (i = 0; i < count; i++) {
- /* ignore group names */
- if (status[i].flags & 0x80) continue;
- if (status[i].type == 0x20) {
- size = sizeof(status[i].name) + 1;
- if (size > len) {
- free(status);
- return NSD_ERROR;
- }
- len -= size;
- strncat(response, status[i].name, size);
- strncat(response, " ", 1);
- found = True;
- }
- }
- response[strlen(response)-1] = '\n';
- free(status);
- }
- } else if (StrCaseCmp(map,"hosts.byname") == 0) {
- if (ip_list = lookup_byname_backend(key, &count)) {
- for (i = count; i ; i--) {
- addr = inet_ntoa(ip_list[i-1]);
- size = strlen(addr) + 1;
- if (size > len) {
- free(ip_list);
- return NSD_ERROR;
- }
- len -= size;
- if (i != 0)
- response[strlen(response)-1] = ' ';
- strncat(response,addr,size);
- strncat(response,"\t",1);
- }
- size = strlen(key) + 1;
- if (size > len) {
- free(ip_list);
- return NSD_ERROR;
- }
- strncat(response,key,size);
- strncat(response,"\n",1);
- found = True;
- free(ip_list);
- }
- }
-
- if (found) {
- nsd_logprintf(NSD_LOG_LOW, "lookup (wins %s) %s\n",map,response);
- nsd_set_result(rq,NS_SUCCESS,response,strlen(response),VOLATILE);
- return NSD_OK;
- }
- nsd_logprintf(NSD_LOG_LOW, "lookup (wins) not found\n");
- rq->f_status = NS_NOTFOUND;
- return NSD_NEXT;
-}
-
-#else
-
-/* Allocate some space from the nss static buffer. The buffer and buflen
- are the pointers passed in by the C library to the _nss_*_*
- functions. */
-
-static char *get_static(char **buffer, size_t *buflen, int len)
-{
- char *result;
-
- /* Error check. We return false if things aren't set up right, or
- there isn't enough buffer space left. */
-
- if ((buffer == NULL) || (buflen == NULL) || (*buflen < len)) {
- return NULL;
- }
-
- /* Return an index into the static buffer */
-
- result = *buffer;
- *buffer += len;
- *buflen -= len;
-
- return result;
-}
-
-/****************************************************************************
-gethostbyname() - we ignore any domain portion of the name and only
-handle names that are at most 15 characters long
- **************************************************************************/
-NSS_STATUS
-_nss_wins_gethostbyname_r(const char *hostname, struct hostent *he,
- char *buffer, size_t buflen, int *h_errnop)
-{
- NSS_STATUS nss_status = NSS_STATUS_SUCCESS;
- struct in_addr *ip_list;
- int i, count;
- fstring name;
- size_t namelen;
-
-#if HAVE_PTHREAD
- pthread_mutex_lock(&wins_nss_mutex);
-#endif
-
- memset(he, '\0', sizeof(*he));
- fstrcpy(name, hostname);
-
- /* Do lookup */
-
- ip_list = lookup_byname_backend(name, &count);
-
- if (!ip_list) {
- nss_status = NSS_STATUS_NOTFOUND;
- goto out;
- }
-
- /* Copy h_name */
-
- namelen = strlen(name) + 1;
-
- if ((he->h_name = get_static(&buffer, &buflen, namelen)) == NULL) {
- free(ip_list);
- nss_status = NSS_STATUS_TRYAGAIN;
- goto out;
- }
-
- memcpy(he->h_name, name, namelen);
-
- /* Copy h_addr_list, align to pointer boundary first */
-
- if ((i = (unsigned long)(buffer) % sizeof(char*)) != 0)
- i = sizeof(char*) - i;
-
- if (get_static(&buffer, &buflen, i) == NULL) {
- free(ip_list);
- nss_status = NSS_STATUS_TRYAGAIN;
- goto out;
- }
-
- if ((he->h_addr_list = (char **)get_static(
- &buffer, &buflen, (count + 1) * sizeof(char *))) == NULL) {
- free(ip_list);
- nss_status = NSS_STATUS_TRYAGAIN;
- goto out;
- }
-
- for (i = 0; i < count; i++) {
- if ((he->h_addr_list[i] = get_static(&buffer, &buflen,
- INADDRSZ)) == NULL) {
- free(ip_list);
- nss_status = NSS_STATUS_TRYAGAIN;
- goto out;
- }
- memcpy(he->h_addr_list[i], &ip_list[i], INADDRSZ);
- }
-
- he->h_addr_list[count] = NULL;
-
- free(ip_list);
-
- /* Set h_addr_type and h_length */
-
- he->h_addrtype = AF_INET;
- he->h_length = INADDRSZ;
-
- /* Set h_aliases */
-
- if ((i = (unsigned long)(buffer) % sizeof(char*)) != 0)
- i = sizeof(char*) - i;
-
- if (get_static(&buffer, &buflen, i) == NULL) {
- nss_status = NSS_STATUS_TRYAGAIN;
- goto out;
- }
-
- if ((he->h_aliases = (char **)get_static(
- &buffer, &buflen, sizeof(char *))) == NULL) {
- nss_status = NSS_STATUS_TRYAGAIN;
- goto out;
- }
-
- he->h_aliases[0] = NULL;
-
- nss_status = NSS_STATUS_SUCCESS;
-
- out:
-
-#if HAVE_PTHREAD
- pthread_mutex_unlock(&wins_nss_mutex);
-#endif
- return nss_status;
-}
-
-
-NSS_STATUS
-_nss_wins_gethostbyname2_r(const char *name, int af, struct hostent *he,
- char *buffer, size_t buflen, int *h_errnop)
-{
- NSS_STATUS nss_status;
-
- if(af!=AF_INET) {
- *h_errnop = NO_DATA;
- nss_status = NSS_STATUS_UNAVAIL;
- } else {
- nss_status = _nss_wins_gethostbyname_r(
- name, he, buffer, buflen, h_errnop);
- }
- return nss_status;
-}
-#endif