From 5aa2dc8085d65c8cfcc46a02ee74ddb9d9032e62 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 18 Dec 2016 03:59:10 -0500 Subject: Rename packages to make goimports happy. BREAKING CHANGE. --- nslcd_proto/nslcd_h.go | 454 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 454 insertions(+) create mode 100644 nslcd_proto/nslcd_h.go (limited to 'nslcd_proto/nslcd_h.go') diff --git a/nslcd_proto/nslcd_h.go b/nslcd_proto/nslcd_h.go new file mode 100644 index 0000000..cb210cd --- /dev/null +++ b/nslcd_proto/nslcd_h.go @@ -0,0 +1,454 @@ +// This file is based heavily on nslcd.h from nss-pam-ldapd +// Copyright (C) 2015 Luke Shumaker +/* + nslcd.h - file describing client/server protocol + + Copyright (C) 2006 West Consulting + Copyright (C) 2006, 2007, 2009, 2010, 2011, 2012, 2013 Arthur de Jong + + 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 2.1 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 + Lesser 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, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +package nslcd_proto + +import ( + "fmt" + "io" + "net" +) + +/* + The protocol used between the nslcd client and server is a simple binary + protocol. It is request/response based where the client initiates a + connection, does a single request and closes the connection again. Any + mangled or not understood messages will be silently ignored by the server. + + A request looks like: + INT32 NSLCD_VERSION + INT32 NSLCD_ACTION_* + [request parameters if any] + A response looks like: + INT32 NSLCD_VERSION + INT32 NSLCD_ACTION_* (the original request type) + [result(s)] + INT32 NSLCD_RESULT_END + A single result entry looks like: + NSLCD_RESULT_BEGIN int32 + [result value(s)] + If a response would return multiple values (e.g. for NSLCD_ACTION_*_ALL + functions) each return value will be preceded by a NSLCD_RESULT_BEGIN + value. After the last returned result the server sends + NSLCD_RESULT_END. If some error occurs (e.g. LDAP server unavailable, + error in the request, etc) the server terminates the connection to signal + an error condition (breaking the protocol). + + These are the available basic data types: + INT32 - 32-bit integer value + TYPE - a typed field that is transferred using sizeof() + STRING - a string length (32bit) followed by the string value (not + null-terminted) the string itself is assumed to be UTF-8 + STRINGLIST - a 32-bit number noting the number of strings followed by + the strings one at a time + + Furthermore the ADDRESS compound data type is defined as: + INT32 type of address: e.g. AF_INET or AF_INET6 + INT32 lenght of address + RAW the address itself + With the ADDRESSLIST using the same construct as with STRINGLIST. + + The protocol uses network byte order for all types. +*/ +// These basic data types are implemented in `io.go` + +/* The current version of the protocol. This protocol should only be + updated with major backwards-incompatible changes. */ +const NSLCD_VERSION int32 = 0x00000002 + +/* Get a NSLCD configuration option. There is one request parameter: */ +type Request_Config_Get struct { + Key int32 /* NSLCD_CONFIG_* */ +} +/* the result value is: */ +type Config struct { + Value string /* interpretation depending on request */ +} +const NSLCD_ACTION_CONFIG_GET int32 = 0x00010001 + +const ( + /* return the message, if any, that is presented to the user when password + modification through PAM is prohibited */ + NSLCD_CONFIG_PAM_PASSWORD_PROHIBIT_MESSAGE int32 = 1 +) + +/* Email alias (/etc/aliases) NSS requests. The result values for a + single entry are: */ +type Alias struct { + Name string + Recipients []string +} +const NSLCD_ACTION_ALIAS_BYNAME int32 = 0x00020001; type Request_Alias_ByName struct { Name string } +const NSLCD_ACTION_ALIAS_ALL int32 = 0x00020008; type Request_Alias_All struct {} + +/* Ethernet address/name mapping NSS requests. The result values for a + single entry are: */ +type Ether struct { + Name string + Address [6]byte +} +const NSLCD_ACTION_ETHER_BYNAME int32 = 0x00030001; type Request_Ether_ByName struct { Name string } +const NSLCD_ACTION_ETHER_BYETHER int32 = 0x00030002; type Request_Ether_ByEther struct { Ether [6]byte } +const NSLCD_ACTION_ETHER_ALL int32 = 0x00030008; type Request_Ether_All struct {} + +/* Group and group membership related NSS requests. The result values + for a single entry are: */ +type Group struct { + Name string + PwHash string + ID int32 + Members []string +} +/* (note that the BYMEMER call returns an emtpy members list) */ +const NSLCD_ACTION_GROUP_BYNAME int32 = 0x00040001; type Request_Group_ByName struct { Name string } +const NSLCD_ACTION_GROUP_BYGID int32 = 0x00040002; type Request_Group_ByGid struct { Gid int32 } +const NSLCD_ACTION_GROUP_BYMEMBER int32 = 0x00040006; type Request_Group_ByMember struct { Member string } +const NSLCD_ACTION_GROUP_ALL int32 = 0x00040008; type Request_Group_All struct {} + +/* Hostname (/etc/hosts) lookup NSS requests. The result values + for an entry are: */ +type Host struct { + Name string + Aliases []string + Addresses []net.IP +} +const NSLCD_ACTION_HOST_BYNAME int32 = 0x00050001; type Request_Host_ByName struct { Name string } +const NSLCD_ACTION_HOST_BYADDR int32 = 0x00050002; type Request_Host_ByAddr struct { Addr net.IP } +const NSLCD_ACTION_HOST_ALL int32 = 0x00050008; type Request_Host_All struct {} + +/* Netgroup NSS result entries contain a number of parts. A result entry + starts with: + STRING netgroup name + followed by zero or more references to other netgroups or netgroup + triples. A reference to another netgroup looks like: + INT32 NSLCD_NETGROUP_TYPE_NETGROUP + STRING other netgroup name + A a netgroup triple looks like: + INT32 NSLCD_NETGROUP_TYPE_TRIPLE + STRING host + STRING user + STRING domain + A netgroup result entry is terminated by: + INT32 NSLCD_NETGROUP_TYPE_END + */ +type Netgroup_Netgroup struct { + Name string +} +type Netgroup_Triple struct { + Host string + User string + Domain string +} +type Netgroup_PartList []interface{} +func (data Netgroup_PartList) nslcdWrite(fd io.Writer) { + for _, part := range data { + var t int32 = -1 + switch part.(type) { + case Netgroup_Netgroup: + t = NSLCD_NETGROUP_TYPE_NETGROUP + case Netgroup_Triple: + t = NSLCD_NETGROUP_TYPE_TRIPLE + } + if t < 0 { + panic("unrecognized netgroup type") + } + Write(fd, t) + Write(fd, part) + } + Write(fd, NSLCD_NETGROUP_TYPE_END) +} +func (data *Netgroup_PartList) nslcdRead(fd io.Reader) { + *data = make([]interface{}, 0) + for { + var t int32 + var v interface{} + Read(fd, &t) + switch t { + case NSLCD_NETGROUP_TYPE_NETGROUP: + v = Netgroup_Netgroup{} + case NSLCD_NETGROUP_TYPE_TRIPLE: + v = Netgroup_Triple{} + case NSLCD_NETGROUP_TYPE_END: + return + default: + panic(NslcdError(fmt.Sprintf("unrecognized netgroup type: %#08x", t))) + } + Read(fd, &v) + *data = append(*data, v) + } +} +var _ nslcdObject = Netgroup_PartList{} +var _ nslcdObjectPtr = &Netgroup_PartList{} +type Netgroup struct { + Name string + Parts Netgroup_PartList +} +const NSLCD_ACTION_NETGROUP_BYNAME int32 = 0x00060001; type Request_Netgroup_ByName struct { Name string } +const NSLCD_ACTION_NETGROUP_ALL int32 = 0x00060008; type Request_Netgroup_All struct {} +const ( + NSLCD_NETGROUP_TYPE_NETGROUP int32 = 1 + NSLCD_NETGROUP_TYPE_TRIPLE int32 = 2 + NSLCD_NETGROUP_TYPE_END int32 = 3 +) + +/* Network name (/etc/networks) NSS requests. Result values for a single + entry are: */ +type Network struct { + Name string + Aliases []string + Addresses []net.IP +} +const NSLCD_ACTION_NETWORK_BYNAME int32 = 0x00070001; type Request_Network_ByName struct { Name string } +const NSLCD_ACTION_NETWORK_BYADDR int32 = 0x00070002; type Request_Network_ByAddr struct { Addr net.IP } +const NSLCD_ACTION_NETWORK_ALL int32 = 0x00070008; type Request_Network_All struct {} + +/* User account (/etc/passwd) NSS requests. Result values are: */ +type Passwd struct { + Name string + PwHash string + UID int32 + GID int32 + GECOS string + HomeDir string + Shell string +} +const NSLCD_ACTION_PASSWD_BYNAME int32 = 0x00080001; type Request_Passwd_ByName struct { Name string } +const NSLCD_ACTION_PASSWD_BYUID int32 = 0x00080002; type Request_Passwd_ByUID struct { UID int32 } +const NSLCD_ACTION_PASSWD_ALL int32 = 0x00080008; type Request_Passwd_All struct {} + +/* Protocol information requests. Result values are: */ +type Protocol struct { + Name string + Aliases []string + Number int32 +} +const NSLCD_ACTION_PROTOCOL_BYNAME int32 = 0x00090001; type Request_Protocol_ByName struct { Name string } +const NSLCD_ACTION_PROTOCOL_BYNUMBER int32 = 0x00090002; type Request_Protocol_ByNumber struct { Number int32 } +const NSLCD_ACTION_PROTOCOL_ALL int32 = 0x00090008; type Request_Protocol_All struct {} + +/* RPC information requests. Result values are: */ +type RPC struct { + Name string + Aliases []string + Number int32 +} +const NSLCD_ACTION_RPC_BYNAME int32 = 0x000a0001; type Request_RPC_ByName struct { Name string } +const NSLCD_ACTION_RPC_BYNUMBER int32 = 0x000a0002; type Request_RPC_ByNumber struct { Number int32 } +const NSLCD_ACTION_RPC_ALL int32 = 0x000a0008; type Request_RPC_All struct {} + +/* Service (/etc/services) information requests. The BYNAME and BYNUMBER + requests contain an extra protocol string in the request which, if not + blank, will filter the services by this protocol. Result values are: */ +type Service struct { + Name string + Aliases []string + PortNumber int32 + Protocol string +} +const NSLCD_ACTION_SERVICE_BYNAME int32 = 0x000b0001; type Request_Service_ByName struct { Name string } +const NSLCD_ACTION_SERVICE_BYNUMBER int32 = 0x000b0002; type Request_Service_ByNumber struct { Number int32 } +const NSLCD_ACTION_SERVICE_ALL int32 = 0x000b0008; type Request_Service_All struct {} + +/* Extended user account (/etc/shadow) information requests. Result + values for a single entry are: */ +type Shadow struct { + // It is my understanding that an empty value for an INT32 + // field is expressed with a negative number. -- lukeshu + Name string + PwHash string + LastChangeDate int32 + MinDays int32 + MaxDays int32 + WarnDays int32 + InactDays int32 + ExpireDate int32 + Flag int32 +} +const NSLCD_ACTION_SHADOW_BYNAME int32 = 0x000c0001; type Request_Shadow_ByName struct { Name string } +const NSLCD_ACTION_SHADOW_ALL int32 = 0x000c0008; type Request_Shadow_All struct {} + +/* PAM-related requests. The request parameters for all these requests + begin with: */ +type PAM_Base struct { + UserName string + ServiceName string + RUser string + RHost string + TTY string +} +/* If the user is not known in LDAP no result may be returned (immediately + return NSLCD_RESULT_END instead of a PAM error code). */ + +/* PAM authentication check request. The extra request values are: */ +type Request_PAM_Authentication struct { + PAM_Base + Password string +} +/* and the result value consists of: */ +type PAM_Authentication struct { + AuthenticationResult int32 + UserName string + AuthorizationResult int32 + AuthorizationError string +} +/* If the username is empty in this request an attempt is made to + authenticate as the administrator (set using rootpwmoddn). + Some authorisation checks are already done during authentication so the + response also includes authorisation information. */ +const NSLCD_ACTION_PAM_AUTHENTICATION int32 = 0x000d0001 + +/* PAM authorisation check request. The result value consists of: */ +type PAM_Authorization struct { + Result int32 + Error string +} +/* The authentication check may have already returned some authorisation + information. The authorisation error message, if supplied, will be used + by the PAM module instead of a message that is generated by the PAM + module itself. */ +const NSLCD_ACTION_PAM_AUTHORIZATION int32 = 0x000d0002; type Request_PAM_Authorization PAM_Base + +/* PAM session open request. The result value consists of: */ +type PAM_SessionOpen struct { + SessionID string +} +/* This session id may be used to close this session with. */ +const NSLCD_ACTION_PAM_SESSIONOPEN int32 = 0x000d0003; type Request_PAM_SessionOpen PAM_Base + +/* PAM session close request. This request has the following + extra request value: */ +type Request_PAM_SessionClose struct { + PAM_Base + SessionID string +} +/* and this calls only returns an empty response value. */ +type PAM_SessionClose struct {} +const NSLCD_ACTION_PAM_SESSIONCLOSE int32 = 0x000d0004 + +/* PAM password modification request. This requests has the following extra + request values: */ +type Request_PAM_PwMod struct { + PAM_Base + AsRoot int32 /* 0=oldpasswd is user passwd, 1=oldpasswd is root passwd */ + OldPassword string + NewPassword string +} +/* and returns the result values: */ +type PAM_PwMod struct { + Result int32 + Error string +} +const NSLCD_ACTION_PAM_PWMOD int32 = 0x000d0005 + +/* User information change request. This request allows one to change + their full name and other information. The request parameters for this + request are: + STRING user name + INT32 asroot: 0=passwd is user passwd, 1=passwd is root passwd + STRING password + followed by one or more of the below, terminated by NSLCD_USERMOD_END + INT32 NSLCD_USERMOD_* + STRING new value + the response consists of one or more of the entries below, terminated + by NSLCD_USERMOD_END: + INT32 NSLCD_USERMOD_* + STRING response + (if the response is blank, the change went OK, otherwise the string + contains an error message) + */ +type UserMod_Item struct { + Key int32 + Value string +} +type UserMod_ItemList []UserMod_Item +func (data UserMod_ItemList) nslcdWrite(fd io.Writer) { + for _, item := range data { + Write(fd, item) + } + Write(fd, NSLCD_USERMOD_END) +} +func (data *UserMod_ItemList) nslcdRead(fd io.Reader) { + *data = make([]UserMod_Item, 0) + for { + var t int32 + Read(fd, &t) + if t == NSLCD_USERMOD_END { + return + } + var v UserMod_Item + Read(fd, &v) + *data = append(*data, v) + } +} +var _ nslcdObject = UserMod_ItemList{} +var _ nslcdObjectPtr = &UserMod_ItemList{} +type Request_UserMod struct { + UserName string + AsRoot int32 + Password string + Items UserMod_ItemList +} +type UserMod struct { + Items []UserMod_Item +} +const NSLCD_ACTION_USERMOD int32 = 0x000e0001 + +/* These are the possible values for the NSLCD_ACTION_USERMOD operation + above. */ +const ( + NSLCD_USERMOD_END int32 = 0 /* end of change values */ + NSLCD_USERMOD_RESULT int32 = 1 /* global result value */ + NSLCD_USERMOD_FULLNAME int32 = 2 /* full name */ + NSLCD_USERMOD_ROOMNUMBER int32 = 3 /* room number */ + NSLCD_USERMOD_WORKPHONE int32 = 4 /* office phone number */ + NSLCD_USERMOD_HOMEPHONE int32 = 5 /* home phone number */ + NSLCD_USERMOD_OTHER int32 = 6 /* other info */ + NSLCD_USERMOD_HOMEDIR int32 = 7 /* home directory */ + NSLCD_USERMOD_SHELL int32 = 8 /* login shell */ +) + +/* Request result codes. */ +const ( + NSLCD_RESULT_BEGIN int32 = 1 + NSLCD_RESULT_END int32 = 2 +) + +/* Partial list of PAM result codes. */ +const ( + NSLCD_PAM_SUCCESS int32 = 0 /* everything ok */ + NSLCD_PAM_PERM_DENIED int32 = 6 /* Permission denied */ + NSLCD_PAM_AUTH_ERR int32 = 7 /* Authc failure */ + NSLCD_PAM_CRED_INSUFFICIENT int32 = 8 /* Cannot access authc data */ + NSLCD_PAM_AUTHINFO_UNAVAIL int32 = 9 /* Cannot retrieve authc info */ + NSLCD_PAM_USER_UNKNOWN int32 = 10 /* User not known */ + NSLCD_PAM_MAXTRIES int32 = 11 /* Retry limit reached */ + NSLCD_PAM_NEW_AUTHTOK_REQD int32 = 12 /* Password expired */ + NSLCD_PAM_ACCT_EXPIRED int32 = 13 /* Account expired */ + NSLCD_PAM_SESSION_ERR int32 = 14 /* Cannot make/remove session record */ + NSLCD_PAM_AUTHTOK_ERR int32 = 20 /* Authentication token manipulation error */ + NSLCD_PAM_AUTHTOK_DISABLE_AGING int32 = 23 /* Password aging disabled */ + NSLCD_PAM_IGNORE int32 = 25 /* Ignore module */ + NSLCD_PAM_ABORT int32 = 26 /* Fatal error */ + NSLCD_PAM_AUTHTOK_EXPIRED int32 = 27 /* authentication token has expired */ +) -- cgit v1.2.3