~ubuntu-branches/ubuntu/natty/gnome-keyring/natty

« back to all changes in this revision

Viewing changes to pam/gkr-pam-client.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2010-02-16 19:00:06 UTC
  • mfrom: (1.1.58 upstream)
  • Revision ID: james.westby@ubuntu.com-20100216190006-cqpnic4zxlkmmi0o
Tags: 2.29.90git20100218-0ubuntu1
Updated to a git snapshot version

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
#include "egg/egg-buffer.h"
29
29
#include "egg/egg-unix-credentials.h"
30
30
 
 
31
#include "daemon/control/gkd-control-codes.h"
 
32
 
31
33
#include <sys/types.h>
 
34
#include <sys/param.h>
32
35
#include <sys/socket.h>
33
36
#include <sys/stat.h>
34
37
#include <sys/un.h>
54
57
#include <sys/ucred.h>
55
58
#endif
56
59
 
57
 
#define PAM_APP_NAME      "Auto Login (PAM)"
58
 
#define PAM_APP_NAME_LEN  (sizeof (PAM_APP_NAME) - 1)
59
 
 
60
60
static int
61
61
check_peer_same_uid (int sock)
62
62
{
143
143
}
144
144
 
145
145
static int
146
 
connect_to_daemon (const char *path)
 
146
connect_to_daemon (const char *control)
147
147
{
 
148
        char path[MAXPATHLEN];
148
149
        struct sockaddr_un addr;
149
150
        struct stat st;
150
151
        int sock;
151
 
        
152
 
        /* First a bunch of checks to make sure nothing funny is going on */
153
 
        
 
152
 
 
153
        /* Build up the directory name */
 
154
        if (strlen (control) + strlen ("/control") + 1 >= MAXPATHLEN) {
 
155
                syslog (GKR_LOG_ERR, "The gnome keyring socket directory is too long");
 
156
                return -1;
 
157
        }
 
158
        strcpy (path, control);
 
159
        strcat (path, "/control");
 
160
 
 
161
        /* A bunch of checks to make sure nothing funny is going on */
154
162
        if (lstat (path, &st) < 0) {
155
 
                syslog (GKR_LOG_ERR, "Couldn't access gnome keyring socket: %s: %s", 
 
163
                syslog (GKR_LOG_ERR, "Couldn't access gnome keyring socket: %s: %s",
156
164
                        path, strerror (errno));
157
165
                return -1;
158
166
        }
176
184
        
177
185
        sock = socket (AF_UNIX, SOCK_STREAM, 0);
178
186
        if (sock < 0) {
179
 
                syslog (GKR_LOG_ERR, "couldn't create socket: %s", strerror (errno));
 
187
                syslog (GKR_LOG_ERR, "couldn't create control socket: %s", strerror (errno));
180
188
                return -1;
181
189
        }
182
190
 
184
192
        fcntl (sock, F_SETFD, 1);
185
193
 
186
194
        if (connect (sock, (struct sockaddr*) &addr, sizeof (addr)) < 0) {
187
 
                syslog (GKR_LOG_ERR, "couldn't connect to daemon at: %s: %s", 
 
195
                syslog (GKR_LOG_ERR, "couldn't connect to gnome-keyring-daemon socket at: %s: %s",
188
196
                        path, strerror (errno));
189
197
                close (sock);
190
198
                return -1;
208
216
}
209
217
 
210
218
static void
211
 
write_part (int fd, const unsigned char *data, int len, GnomeKeyringResult *res)
 
219
write_part (int fd, const unsigned char *data, int len, int *res)
212
220
{
213
221
        assert (res);
214
222
        
215
223
        /* Already an error present */
216
 
        if (*res != GNOME_KEYRING_RESULT_OK)
 
224
        if (*res != GKD_CONTROL_RESULT_OK)
217
225
                return;
218
226
        
219
227
        assert (data);
225
233
                                continue;
226
234
                        syslog (GKR_LOG_ERR, "couldn't send data to gnome-keyring-daemon: %s", 
227
235
                                strerror (errno));
228
 
                        *res = GNOME_KEYRING_RESULT_IO_ERROR;
 
236
                        *res = GKD_CONTROL_RESULT_FAILED;
229
237
                        return;
230
238
                }
231
239
                data += r;
261
269
        return all;
262
270
}
263
271
 
264
 
static GnomeKeyringResult 
265
 
keyring_daemon_op (const char *socket, GnomeKeyringOpCode op, int argc, 
266
 
                   const char* argv[])
 
272
static int
 
273
keyring_daemon_op (const char *control, int op, int argc, const char* argv[])
267
274
{
268
 
        GnomeKeyringResult ret = GNOME_KEYRING_RESULT_OK;
 
275
        int ret = GKD_CONTROL_RESULT_OK;
269
276
        unsigned char buf[4];
270
277
        int i, sock = -1;
271
278
        uint oplen, l;
272
 
        
273
 
        assert (socket);
274
 
        
 
279
 
 
280
        assert (control);
 
281
 
275
282
        /* 
276
283
         * We only support operations with zero or more strings
277
284
         * and an empty (only result code) return. 
278
285
         */
279
286
         
280
 
        assert (op == GNOME_KEYRING_OP_UNLOCK_KEYRING || 
281
 
                op == GNOME_KEYRING_OP_CREATE_KEYRING || 
282
 
                op == GNOME_KEYRING_OP_CHANGE_KEYRING_PASSWORD);
 
287
        assert (op == GKD_CONTROL_OP_CHANGE || op == GKD_CONTROL_OP_UNLOCK);
283
288
 
284
 
        sock = connect_to_daemon (socket);
 
289
        sock = connect_to_daemon (control);
285
290
        if (sock < 0) {
286
291
                ret = -1;
287
292
                goto done;
288
293
        }
289
 
        
290
 
        /* Send the application packet / name */
291
 
        egg_buffer_encode_uint32 (buf, PAM_APP_NAME_LEN + 8);
292
 
        write_part (sock, buf, 4, &ret);
293
 
        egg_buffer_encode_uint32 (buf, PAM_APP_NAME_LEN);
294
 
        write_part (sock, buf, 4, &ret);
295
 
        write_part (sock, (unsigned char*)PAM_APP_NAME, PAM_APP_NAME_LEN, &ret);
296
 
            
 
294
 
297
295
        /* Calculate the packet length */
298
296
        oplen = 8; /* The packet size, and op code */
299
297
        for (i = 0; i < argc; ++i)  
317
315
                        write_part (sock, (unsigned char*)argv[i], l, &ret);
318
316
        }
319
317
        
320
 
        if (ret != GNOME_KEYRING_RESULT_OK)
 
318
        if (ret != GKD_CONTROL_RESULT_OK)
321
319
                goto done;
322
320
                
323
321
        /* Read the response length */
324
322
        if (read_part (sock, buf, 4) != 4) {
325
 
                ret = GNOME_KEYRING_RESULT_IO_ERROR;
 
323
                ret = GKD_CONTROL_RESULT_FAILED;
326
324
                goto done;
327
325
        }
328
326
 
330
328
        l = egg_buffer_decode_uint32 (buf);
331
329
        if (l != 8) {
332
330
                syslog (GKR_LOG_ERR, "invalid length response from gnome-keyring-daemon: %d", l);
333
 
                ret = GNOME_KEYRING_RESULT_IO_ERROR;
 
331
                ret = GKD_CONTROL_RESULT_FAILED;
334
332
                goto done;
335
333
        }
336
334
 
337
335
        if (read_part (sock, buf, 4) != 4) {
338
 
                ret = GNOME_KEYRING_RESULT_IO_ERROR;
 
336
                ret = GKD_CONTROL_RESULT_FAILED;
339
337
                goto done;
340
338
        }
341
339
        ret = egg_buffer_decode_uint32 (buf);
347
345
        return ret;
348
346
}
349
347
 
350
 
GnomeKeyringResult
351
 
gkr_pam_client_run_operation (struct passwd *pwd, const char *socket, 
352
 
                              GnomeKeyringOpCode op, int argc, const char* argv[])
 
348
int
 
349
gkr_pam_client_run_operation (struct passwd *pwd, const char *control,
 
350
                              int op, int argc, const char* argv[])
353
351
{
354
352
        struct sigaction ignpipe, oldpipe, defchld, oldchld;
355
 
        GnomeKeyringResult res;
 
353
        int res;
356
354
        pid_t pid;
357
355
        int status;
358
356
        
371
369
            pwd->pw_uid == geteuid () && pwd->pw_gid == getegid ()) {
372
370
 
373
371
                /* Already running as the right user, simple */
374
 
                res = keyring_daemon_op (socket, op, argc, argv);
 
372
                res = keyring_daemon_op (control, op, argc, argv);
375
373
                
376
374
        } else {
377
375
                
380
378
                case -1:
381
379
                        syslog (GKR_LOG_ERR, "gkr-pam: couldn't fork: %s", 
382
380
                                strerror (errno));
383
 
                        res = GNOME_KEYRING_RESULT_IO_ERROR;
 
381
                        res = GKD_CONTROL_RESULT_FAILED;
384
382
                        break;
385
383
                        
386
384
                case 0:
389
387
                            setegid (pwd->pw_gid) < 0 || seteuid (pwd->pw_uid) < 0) {
390
388
                                syslog (GKR_LOG_ERR, "gkr-pam: couldn't switch to user: %s: %s", 
391
389
                                        pwd->pw_name, strerror (errno));
392
 
                                exit (GNOME_KEYRING_RESULT_IO_ERROR);
 
390
                                exit (GKD_CONTROL_RESULT_FAILED);
393
391
                        }
394
392
        
395
 
                        res = keyring_daemon_op (socket, op, argc, argv);
 
393
                        res = keyring_daemon_op (control, op, argc, argv);
396
394
                        exit (res);
397
395
                        return 0; /* Never reached */
398
396
                        
401
399
                        if (wait (&status) != pid) {
402
400
                                syslog (GKR_LOG_ERR, "gkr-pam: couldn't wait on child process: %s", 
403
401
                                        strerror (errno));
404
 
                                res = GNOME_KEYRING_RESULT_IO_ERROR;
 
402
                                res = GKD_CONTROL_RESULT_FAILED;
405
403
                        }
406
404
                        
407
405
                        res = WEXITSTATUS (status);