diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2008-12-16 15:36:53 +0100 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2008-12-16 15:36:53 +0100 |
commit | a7109b183b555ee795c3e32c63e2647025705fc1 (patch) | |
tree | bc118e6f1dd72466367a4aa9b31df08f253eaa07 /source3/nsswitch | |
parent | 0f04beff337a936a66c86272ff79defd9e8ae173 (diff) | |
parent | 9e64ed018e5aa84d802b01953b481fbb07eb00aa (diff) | |
download | samba-a7109b183b555ee795c3e32c63e2647025705fc1.tar.gz samba-a7109b183b555ee795c3e32c63e2647025705fc1.tar.bz2 samba-a7109b183b555ee795c3e32c63e2647025705fc1.zip |
Merge branch 'master' of ssh://git.samba.org/data/git/samba
Diffstat (limited to 'source3/nsswitch')
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(¶ms, 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(¶ms, - 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(¶ms, &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(¶ms, &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 |