The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
auth_wbclient_pap.c
Go to the documentation of this file.
1 /*
2  * This program is is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or (at
5  * your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /**
18  * $Id: cb91a2ea9766e04cf8a3acb1a2aa31b84f8fbf41 $
19  * @file auth_wbclient_pap.c
20  * @brief PAP authentication against the wbclient library
21  *
22  * @author Matthew Newton (matthew@newtoncomputing.co.uk)
23  *
24  * @copyright 2015-2016 Matthew Newton
25  */
26 
27 RCSID("$Id: cb91a2ea9766e04cf8a3acb1a2aa31b84f8fbf41 $")
28 
29 #include <freeradius-devel/server/base.h>
30 #include <freeradius-devel/util/debug.h>
31 
32 #include <wbclient.h>
33 #include <core/ntstatus.h>
34 
35 #include "rlm_winbind.h"
36 #include "auth_wbclient_pap.h"
37 
38 /** PAP authentication direct to winbind via Samba's libwbclient library
39  *
40  * @param[in] inst Module instance
41  * @param[in] request The current request
42  * @param[in] env The call_env for the current winbind authentication
43  *
44  * @return
45  * - 0 Success
46  * - -1 Authentication failure
47  * - -648 Password expired
48  *
49  */
51 {
52  int ret = -1;
53  struct wbcContext *wb_ctx;
54  struct wbcAuthUserParams authparams;
55  wbcErr err;
56  struct wbcAuthUserInfo *info = NULL;
57  struct wbcAuthErrorInfo *error = NULL;
58 
59  /*
60  * Clear the auth parameters - this is important, as
61  * there are options that will cause wbcAuthenticateUserEx
62  * to bomb out if not zero.
63  */
64  memset(&authparams, 0, sizeof(authparams));
65 
66  /*
67  * username must be set for this function to be called
68  */
69  fr_assert(env->username.type == FR_TYPE_STRING);
70 
71  authparams.account_name = env->username.vb_strvalue;
72 
73  if (env->domain.type == FR_TYPE_STRING) {
74  authparams.domain_name = env->domain.vb_strvalue;
75  } else {
76  RWDEBUG2("No domain specified; authentication may fail because of this");
77  }
78 
79 
80  /*
81  * Build the wbcAuthUserParams structure with what we know
82  */
83  authparams.level = WBC_AUTH_USER_LEVEL_PLAIN;
84  authparams.password.plaintext = env->password.vb_strvalue;
85 
86  /*
87  * Parameters documented as part of the MSV1_0_SUBAUTH_LOGON structure
88  * at https://msdn.microsoft.com/aa378767.aspx
89  */
90  authparams.parameter_control |= WBC_MSV1_0_CLEARTEXT_PASSWORD_ALLOWED |
91  WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT |
92  WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT;
93 
94  /*
95  * Send auth request across to winbind
96  */
97  wb_ctx = fr_pool_connection_get(inst->wb_pool, request);
98  if (wb_ctx == NULL) {
99  RERROR("Unable to get winbind connection from pool");
100  goto done;
101  }
102 
103  RDEBUG2("Sending authentication request user='%s' domain='%s'", authparams.account_name,
104  authparams.domain_name);
105 
106  err = wbcCtxAuthenticateUserEx(wb_ctx, &authparams, &info, &error);
107 
108  fr_pool_connection_release(inst->wb_pool, request, wb_ctx);
109 
110 
111  /*
112  * Try and give some useful feedback on what happened. There are only
113  * a few errors that can actually be returned from wbcCtxAuthenticateUserEx.
114  */
115  switch (err) {
116  case WBC_ERR_SUCCESS:
117  ret = 0;
118  RDEBUG2("Authenticated successfully");
119  break;
120 
121  case WBC_ERR_WINBIND_NOT_AVAILABLE:
122  RERROR("Unable to contact winbindd");
123  RDEBUG2("Check that winbind is running and that FreeRADIUS has");
124  RDEBUG2("permission to connect to the winbind privileged socket");
125  break;
126 
127  case WBC_ERR_DOMAIN_NOT_FOUND:
128  REDEBUG2("Domain not found");
129  break;
130 
131  case WBC_ERR_AUTH_ERROR:
132  if (!error) {
133  REDEBUG2("Authentication failed");
134  break;
135  }
136 
137  /*
138  * The password needs to be changed, set ret appropriately.
139  */
140  if (error->nt_status == NT_STATUS_PASSWORD_EXPIRED ||
141  error->nt_status == NT_STATUS_PASSWORD_MUST_CHANGE) {
142  ret = -648;
143  }
144 
145  /*
146  * Return the NT_STATUS human readable error string, if there is one.
147  */
148  if (error->display_string) {
149  REDEBUG2("%s [0x%X]", error->display_string, error->nt_status);
150  } else {
151  REDEBUG2("Unknown authentication failure [0x%X]", error->nt_status);
152  }
153  break;
154 
155  default:
156  /*
157  * Only errors left are
158  * WBC_ERR_INVALID_PARAM
159  * WBC_ERR_NO_MEMORY
160  * neither of which are particularly likely.
161  */
162  if (error && error->display_string) {
163  REDEBUG2("Failed authenticating user: %s (%s)", error->display_string, wbcErrorString(err));
164  } else {
165  REDEBUG2("Failed authenticating user: Winbind error (%s)", wbcErrorString(err));
166  }
167  break;
168  }
169 
170 
171 done:
172  if (info) wbcFreeMemory(info);
173  if (error) wbcFreeMemory(error);
174 
175  return ret;
176 }
177 
int do_auth_wbclient_pap(rlm_winbind_t const *inst, request_t *request, winbind_auth_call_env_t *env)
PAP authentication direct to winbind via Samba's libwbclient library.
#define RCSID(id)
Definition: build.h:481
static fr_slen_t err
Definition: dict.h:821
#define RWDEBUG2(fmt,...)
Definition: log.h:362
#define RERROR(fmt,...)
Definition: log.h:298
#define REDEBUG2(fmt,...)
Definition: log.h:372
@ FR_TYPE_STRING
String of printable characters.
Definition: merged_model.c:83
void fr_pool_connection_release(fr_pool_t *pool, request_t *request, void *conn)
Release a connection.
Definition: pool.c:1407
void * fr_pool_connection_get(fr_pool_t *pool, request_t *request)
Reserve a connection in the connection pool.
Definition: pool.c:1392
static bool done
Definition: radclient.c:80
#define RDEBUG2(fmt,...)
Definition: radclient.h:54
fr_value_box_t password
Definition: rlm_winbind.h:22
fr_value_box_t domain
Definition: rlm_winbind.h:21
fr_value_box_t username
Definition: rlm_winbind.h:20
fr_assert(0)
eap_aka_sim_process_conf_t * inst