Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com To: cygwin AT cygwin DOT com Subject: Pb with permissions on crontab From: Julien Gilles Date: Fri, 27 Feb 2004 17:15:30 +0100 Message-ID: <87znb4h525.fsf@jgilles.internal.glmultimedia.com> User-Agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-IsSubscribed: yes Hi, I'am playing with cron, and I have the following problem : I want to modify the crontab through a service (a cgi in an apache server in fact). This service belongs to the user SYSTEM, so I used "crontab -u Administrator file" to set the Administrator's crontab (in a perl cgi script). It works fine, the jobs are correctly executed, but the owner of /var/cron/tabs/Administrator is now SYSTEM, and not Administrator. So 'crontab -l' in a shell fails with the following message : "tabs/Administrateur: Permission denied". I tried to play with ACL of /var/cron/tabs/Administrator, but with no luck (ie no way to keep owner). In crontab.c, I find this : #else /* __CYGWIN__ */ if (chown(tn, -1, ROOT_UID) < OK) #endif tn is the temporary crontab, before to be renamed to the user's crontab. If tn is created by SYSTEM, it belongs to SYSTEM, and the user's crontab belongs then to SYSTEM. I first try to force owner to pw->pw_uid, but the rename command then shows me another problem : 'rw' permissions are not enought - even for SYSTEM - to rename a file, there must be other ACL involved. So I end up to force the final crontab to belong to SYSTEM if the euid id SYSTEM, and the to re-change owner after the rename. See the attached patch. It's probably not the best way to solve the problem, but it works for me :-) Tips : for those who wants to play with 'crontab -u' as user SYSTEM, it's possible to have a SYSTEM shell using the windows 'at' command. As Administrator, launch cmd.exe. Run "At 16:07 /interactive cmd.exe" (of course choose the next minute of your local time). The cmd.exe that is launched does have SYSTEM rights. Very useful. To kill services, replace cmd.exe with taskmgr.exe. If you know another way to get SYSTEM shell... *** cron-3.0.1-11/crontab.c Tue Apr 15 17:13:41 2003 --- cron-3.0.1-11.patch/crontab.c Thu Feb 26 15:56:34 2004 *************** *** 666,671 **** --- 666,687 ---- } (void) snprintf(n, sizeof(n), CRON_TAB(User)); + #ifdef __CYGWIN__ + /* A problem appears if -u is used by user SYSTEM : owner of crontab + must be forced, by default it remains SYSTEM (and so no more + available for the user !) */ + struct stat foo; + if ((stat(n, &foo) == 0) && /* test if file exists. I'm not sure that it's the best test... */ + (chown(n, (geteuid() == ROOT_UID)?ROOT_UID:-1, ROOT_UID) < OK)) /* Under CYGWIN 'rw' permissions are not + enough to do a rename. A workaround is + to force ownership, and set it back + after rename */ + { + perror("chown"); + return (-2); + } + + #endif if (rename(tn, n)) { fprintf(stderr, "%s: error renaming %s to %s\n", ProgramName, tn, n); *************** *** 673,678 **** --- 689,707 ---- unlink(tn); return (-2); } + + #ifdef __CYGWIN__ + if (chown(n, pw->pw_uid, ROOT_UID) < OK) /* Set correct owner */ + { + perror("chown"); + return (-2); + } + if (chmod(n, 0640) < OK) /* Force permissions too. */ + { + perror("chmod"); + return (-2); + } + #endif log_it(RealUser, Pid, "REPLACE", User); poke_daemon(); -- Julien Gilles. -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/